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

FREE XDQuest : 6.0.8 6.0.8

Нет прав для скачивания
C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Facepunch.Utility;
using Network;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Rust;
using UnityEngine;
using UnityEngine.Networking;
using Random = Oxide.Core.Random;
namespace Oxide.Plugins {
    [Info("XDQuest", "SkuliDropek", "6.0.8")]
    [Description("Расширенная квест система для вашего сервера!")]
    public class XDQuest : RustPlugin {
        /// <summary> //6.0.8
        /// - Исправлен API для Raidable Bases (Nivex)
        /// - Убрано новогодние оформление
        /// - Добавлена возможность очищать прогресс при вайпе.По стандарту включено в конфигурации
        /// </summary>
#region ReferencePlugins
        [PluginReference]
        Plugin CopyPaste, ImageLibrary, IQChat, Friends, Clans, Battles, Duel, Notify;
        private void SendChat(BasePlayer player, string Message, ConVar.Chat.ChatChannel channel = ConVar.Chat.ChatChannel.Global) {
            if (IQChat) IQChat?.Call("API_ALERT_PLAYER", player, Message, config.settingsIQChat.prifix, config.settingsIQChat.SteamID);
            else player.SendConsoleCommand("chat.add", channel, 0, Message);
        }
        private bool IsFriends(ulong userID, ulong targetID) {
            if (Friends) return (bool)Friends?.Call("HasFriend", userID, targetID);
            else return false;
        }
        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 (bool)(TagUserID == TagTargetID);
            }
            else return false;
        }
        private bool IsDuel(ulong userID) {
            if (Battles) return (bool)Battles?.Call("IsPlayerOnBattle", userID);
            else if (Duel) return (bool)Duel?.Call("IsPlayerOnActiveDuel", BasePlayer.FindByID(userID));
            else return false;
        }
        private string GetImage(string shortname, ulong skin = 0) => (string)ImageLibrary?.Call("GetImage", shortname, skin);
        private void SendImage(BasePlayer player, string imageName, ulong imageId = 0) => ImageLibrary?.Call("SendImage", player, imageName, imageId);
#endregion
#region Variables
        private static XDQuest Instance;
        private static readonly String Key = "OZh9xW02owxY1dd";
        private MonumentInfo monument;
        private BasePlayer npc;
        private ComputerStation chairNpc;
        private List<BaseEntity> HouseNPC = new List<BaseEntity>();
        private static List<uint> Light = new List<uint> {
            1392608348, 110576239, 3341019015, 1797934483, 2409469892, 3887352222, 3953213470
        }
        ;
        private List<Quest> QuestList = new List<Quest>();
        private SafeZone safeZone = null;
        private ZoneTrigger zoneTrigger = null;
        private Dictionary<ulong, PlayerData> playersInfo = new Dictionary<ulong, PlayerData>();
        private class PlayerData {
            public List<string> PlayerQuestsFinish = new List<string>();
            public List<PlayerQuest> PlayerQuestsAll = new List<PlayerQuest>();
            public Dictionary<string, double> PlayerQuestsCooldown = new Dictionary<string, double>();
        }
#endregion
#region Lang
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["XDQUEST_CopyPasteError"]
                = "There was a problem with CopyPaste! Contact the Developer!\nDezLife#1480\nnvk.com/dezlife", ["XDQUEST_CopyPasteSuccessfully"] = "The building has spawned successfully!", ["XDQUEST_BuildingPasteError"] = "There was a problem with spawning the Building! Contact the Developer!\nDezLife#1480\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_BuildingLoad"] = "Initializing building for NPC...", ["XDQUEST_KeyAuth"] = "The plugin did not pass the authentication on the server!\nCheck the plugin version or contact the developer\nDezLife#1480\nvk.com/dezlife", ["XDQUEST_FileNotFoundOnServer"] = "File {0} could not be found on server.Contact the developer\nDezLife#1480\nvk.com/dezlife", ["XDQUEST_ServerNotResponse"] = "Unable to load the file {0}, Server response: {1}.Retrying to download...", ["XDQUEST_FileNotLoad"] = "Downloading the file {0} was unsuccessful.Contact the developer\nDezLife#1480\nvk.com/dezlife", ["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_QuestBtnRefuse"] = "REFUSE", ["XDQUEST_UI_ACTIVEOBJECTIVES"] = "Objective: {0}", ["XDQUEST_UI_MiniQLInfo"] = "{0}\nProgress: {1} / {2}\nQuest: {3}", ["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_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_UI_InsufficientResources"] = "You don't have {0}, you should definitely bring this 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"
            }
            , this);
            lang.RegisterMessages(new Dictionary<string, string> {
                ["XDQUEST_CopyPasteError"]
                = "Возникла проблема с CopyPaste! Обратитесь к разработчику\nDezLife#1480\nvk.com/dezlife", ["XDQUEST_CopyPasteSuccessfully"] = "Постройка успешно заспавнена!", ["XDQUEST_BuildingPasteError"] = "Ошибка спавна поостройки! Обратитесь к разработчику\nDezLife#1480\nvk.com/dezlife", ["XDQUEST_MissingOutPost"] = "У вас отсутствует outpost, вы можете использовать кастомную позицию для постройки", ["XDQUEST_MissingQuests"] = "У вас отсутсвует файл с заданиями, плагин будет работать не коректно!  Создайте его на сайте - https://xdquest.skyplugins.ru/ или используйте стандартный", ["XDQUEST_BuildingLoad"] = "Инициализация постройки для NPC...", ["XDQUEST_KeyAuth"] = "Плагин не смог пройти аунтефикацию на сервере!\n Сверьте версию плагина или свяжитесь с разработчиком\nDezLife#1480\nvk.com/dezlife", ["XDQUEST_FileNotFoundOnServer"] = "Файл {0}, не найден на сервере.Обратитесь к разработчику\nDezLife#1480\nvk.com/dezlife", ["XDQUEST_ServerNotResponse"] = "Невозможно загрузить файл {0}, Ответ сервера: {1}.Пробуем повторить загрузку...", ["XDQUEST_FileNotLoad"] = "Повторная загрузка файла {0}, не увенчалась успехом.Обратитесь к разработчику\nDezLife#1480\nvk.com/dezlife", ["XDQUEST_UI_TASKLIST"] = "СПИСОК ЗАДАНИЙ", ["XDQUEST_UI_Awards"] = "Награды", ["XDQUEST_UI_TASKCount"] = "<color=#42a1f5>{0}</color> ЗАДАНИЙ", ["XDQUEST_UI_CHIPperformed"] = "выполнено", ["XDQUEST_UI_CHIPInProgress"] = "выполняется", ["XDQUEST_UI_QUESTREPEATCAN"] = "можно", ["XDQUEST_UI_QUESTREPEATfForbidden"] = "нельзя", ["XDQUEST_UI_Missing"] = "отсутствует", ["XDQUEST_UI_InfoRepeatInCD"] = "Повторно брать {0}  |  Кд на повторное взятие {1}  |  Сдать добытое {2}", ["XDQUEST_UI_QuestNecessary"] = "нужно", ["XDQUEST_UI_QuestNotNecessary"] = "не нужно", ["XDQUEST_UI_QuestBtnPerformed"] = "ВЫПОЛНЕНО", ["XDQUEST_UI_QuestBtnTake"] = "ВЗЯТЬ", ["XDQUEST_UI_QuestBtnPass"] = "ЗАВЕРШИТЬ", ["XDQUEST_UI_QuestBtnRefuse"] = "ОТКАЗАТЬСЯ", ["XDQUEST_UI_ACTIVEOBJECTIVES"] = "АКТИВНЫЕ ЗАДАЧИ: {0}", ["XDQUEST_UI_MiniQLInfo"] = "{0}\nПрогресс: {1} / {2}\nЗадача: {3}", ["XDQUEST_UI_CMDCustomPosAdd"] = "Вы успешно добавили кастомную позицию для постройки.\n(Вам нужно перезагрузить плагин)\nПовернуть ее можно в конфиге!\nТак же не забудъте включить в конфиге возможность спавнить постройку на кастомной позиции", ["XDQUEST_UI_QuestLimit"] = "У тебя слишком много <color=#4286f4>не законченных</color> заданий!", ["XDQUEST_UI_AlreadyTaken"] = "Вы уже <color=#4286f4>взяли</color> это задание!", ["XDQUEST_UI_AlreadyDone"] = "Вы уже <color=#4286f4>выполняли</color> это задание!", ["XDQUEST_UI_TookTasks"] = "Вы <color=#4286f4>успешно</color> взяли задание {0}", ["XDQUEST_UI_ACTIVECOLDOWN"] = "В данный момент вы не можете взять этот квест", ["XDQUEST_UI_LackOfSpace"] = "Эй, погоди, ты всё <color=#4286f4>не унесёшь</color>, освободи место!", ["XDQUEST_UI_QuestsCompleted"] = "Спасибо, держи свою <color=#4286f4>награду</color>!", ["XDQUEST_UI_PassedTasks"] = "Жаль что ты <color=#4286f4>не справился</color> с заданием!\nВ любом случае, ты можешь попробовать ещё раз!", ["XDQUEST_UI_ActiveQuestCount"] = "У вас нет активных заданий.", ["XDQUEST_Finished_QUEST"] = "Вы выполнили задание: <color=#4286f4>{0}</color>", ["XDQUEST_UI_InsufficientResources"] = "У вас нету {0}, нужно обязательно принести это сидоровичу", ["XDQUEST_UI_NotResourcesAmount"] = "У вас не достаточно {0},  нужно {1}", ["XDQUEST_SoundLoadErrorExt"] = "Отсутсвует голосовой файл {0}, загрузите его по этому пути - (/data/XDQuest/Sounds).Или удалите его из конфигурации"
            }
            , this, "ru");
        }
#endregion
#region Configuration
        private Configuration config;
        private class Configuration {
            public class itemsNpc {
                [JsonProperty("ShortName")]
                public String ShortName;
                [JsonProperty("SkinId")]
                public ulong SkinId;
            }
            public class Settings {
                /*3*/
                [JsonProperty("Максимальное колличевство единовременно взятых квестов")]
                ////[JsonProperty("The maximum number of simultaneously taken quests")]
                public Int32 questCount = 3;
                /*3*/
                [JsonProperty("Голосовое оповещение при выполнении задания")]
                ////[JsonProperty("Voice notification when completing a task")]
                public Boolean SoundEffect = true;
                /*3*/
                [JsonProperty("Включите этот параметр если у вас гниет постройка")]
                ////[JsonProperty("Enable this option if your building is rotting")]
                public Boolean useDecay = false;
                /*3*/
                [JsonProperty("Отчищать прогресс игроков при вайпе ?")]
                ////[JsonProperty("Clear player progress when wipe ?")]
                public Boolean useWipe = true;
                /*3*/
                [JsonProperty("Эфект")]
                ////[JsonProperty("Effect")]
                public String Effect = "assets/prefabs/locks/keypad/effects/lock.code.lock.prefab";
                /*3*/
                [JsonProperty("Names of the file with quests")]
                ////[JsonProperty("Names of the file with quests")]
                public String questListDataName = "Quest";
                /*3*/
                [JsonProperty("Команда для открытия квест листа с прогрессом")]
                ////[JsonProperty("The command to open a quest list with progress")]
                public String questListProgress = "qlist";
                /*3*/
                [JsonProperty("Радиус безопасной зоны (Как в городе нпс)")]
                ////[JsonProperty("Safe Zone Radius (As in NPC City)")]
                public float saveZoneRadius = 25;
                /*3*/
                [JsonProperty("Включить ли радио у нпс в здании ?")]
                ////[JsonProperty("Should the radio be turned on for the NPCs in the building?")]
                public Boolean useRadio = true;
                /*3*/
                [JsonProperty("Ссылка на радио станцию которая будет играть в доме")]
                ////[JsonProperty("Link to the radio station that will play in the house")]
                public String RadioStation = "http://radio.skyplugins.ru:8020/stalker.mp3";
                /*3*/
                [JsonProperty("Использовать метку на внутриигровой карте ? (Требуется https://skyplugins.ru/resources/428/)")]
                ////[JsonProperty("Use a placemark on an in-game map ? (Required https://skyplugins.ru/resources/428/)")]
                public Boolean mapUse = false;
                /*3*/
                [JsonProperty("Имя метки на карте")]
                ////[JsonProperty("Name of the placemark on the map")]
                public String nameMarkerMap = "QUEST ROOM";
                /*3*/
                [JsonProperty("Цвет маркера (без #)")]
                ////[JsonProperty("Marker color (without #)")]
                public String colorMarker = "f3ecad";
                /*3*/
                [JsonProperty("Цвет обводки (без #)")]
                ////[JsonProperty("Outline color (without #)")]
                public String colorOutline = "ff3535";
            }
            public class CustomPosition {
                /*3*/
                [JsonProperty("Использовать кастомную позицию постройки ?")]
                ////[JsonProperty("Use a custom construction position ?")]
                public Boolean useCustomPos = false;
                /*3*/
                [JsonProperty("Позиция постройки")]
                ////[JsonProperty("Construction position")]
                public Vector3 pos = Vector3.zero;
                /*3*/
                [JsonProperty("Поворот постройки (Этим параметром вы можете повернуть постройку)")]
                ////[JsonProperty("Rotate the building (You can use this parameter to rotate the building)")]
                public Int32 rotation = 0;
            }
            public class SettingsNpc {
                /*3*/
                [JsonProperty("Имя нпс")]
                ////[JsonProperty("NPC name")]
                public String Name = "Сидорович\n";
                ///Sidorovich/Сидорович
                /*3*/
                [JsonProperty("id npc (От его ид зависит его внешность)")]
                ////[JsonProperty("npc id (His appearance depends on his ID)")]
                public ulong userId = 21;
                /*3*/
                [JsonProperty("Одежда нпс")]
                ////[JsonProperty("NPC Clothing")]
                public List<itemsNpc> Wear = new List<itemsNpc>();
            }
            public class SettingsIQChat {
                /*3*/
                [JsonProperty("Префикс в чате")]
                ////[JsonProperty("Prefix in the chat")]
                public String prifix = "Sidorovich:";
                /*3*/
                [JsonProperty("SteamID - Для аватарки из профиля стим")]
                ////[JsonProperty("SteamID - For the avatar from the steam profile")]
                public String SteamID = "21";
            }
            public class SettingsNotify {
                /*3*/
                [JsonProperty("Включить уведомления (Требуется - https://codefling.com/plugins/notify)")]
                ////[JsonProperty("Enable notifications (Is required - https://codefling.com/plugins/notify)")]
                public bool useNotify = false;
                /*3*/
                [JsonProperty("Тип уведомления (Требуется - https://codefling.com/plugins/notify)")]
                ////[JsonProperty("Notification Type (Is required - https://codefling.com/plugins/notify)")]
                public int typeNotify = 0;
            }
            public class SettingsSoundNPC {
                /*3*/
                [JsonProperty("Включить возможность разговаривать NPC")]
                ////[JsonProperty("Enable the ability to talk to NPCs")]
                public bool soundUse = true;
                /*3*/
                [JsonProperty("Заполнять стандартными звуками ? (Нужно добавить звуки в дату!)")]
                ////[JsonProperty("Fill it with standard sounds ? (Need to add sounds to the date!)")]
                public bool soundAddToCfg = true;
                /*3*/
                [JsonProperty("Название файлов со звуком для приветствия")]
                ////[JsonProperty("The name of the files with the greeting sound")]
                public List<string> heySound = new List<string>();
                /*3*/
                [JsonProperty("Название файлов со звуком для прощание")]
                ////[JsonProperty("The name of the files with the sound for farewell")]
                public List<string> byeSound = new List<string>();
                /*3*/
                [JsonProperty("Название файлов со звуком для взятие задания")]
                ////[JsonProperty("The name of the files with the sound for taking the task")]
                public List<string> takeQuestSound = new List<string>();
                /*3*/
                [JsonProperty("Название файлов со звуком для сдачи задания")]
                ////[JsonProperty("The name of the files with the sound to complete the task")]
                public List<string> turnQuestSound = new List<string>();
            }
            /*3*/
            [JsonProperty("Настройка кастомной позиции постройки")]
            ////[JsonProperty("Setting up a custom building position")]
            public CustomPosition customPosition = new CustomPosition();
            /*3*/
            [JsonProperty("Настройки NPC")]
            ////[JsonProperty("NPC Settings")]
            public SettingsNpc settingsNpc = new SettingsNpc();
            /*3*/
            [JsonProperty("Настройки")]
            ////[JsonProperty("Settings")]
            public Settings settings = new Settings();
            /*3*/
            [JsonProperty("Настройки звуков/разговоров NPC")]
            ////[JsonProperty("NPC Sound/Conversation Settings")]
            public SettingsSoundNPC settingsSoundNPC = new SettingsSoundNPC();
            /*3*/
            [JsonProperty("Настройки IQChat (Если есть)")]
            ////[JsonProperty("Ichat Settings (If any)")]
            public SettingsIQChat settingsIQChat = new SettingsIQChat();
            /*3*/
            [JsonProperty("Настройки уведомления")]
            ////[JsonProperty("Notification Settings")]
            public SettingsNotify settingsNotify = new SettingsNotify();
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                config = Config.ReadObject<Configuration>();
                if (config == null) throw new Exception();
                SaveConfig();
            }
            catch {
                for (var i = 0; i < 3; i++) PrintError("Configuration file is corrupt! Check your config file at https://jsonlint.com/");
                LoadDefaultConfig();
            }
            ValidateConfig();
            SaveConfig();
        }
        private void ValidateConfig() {
            if (config.settingsNpc.Wear.Count == 0) {
                config.settingsNpc.Wear = new List<Configuration.itemsNpc> {
                    new Configuration.itemsNpc {
                        ShortName = "pants", SkinId = 960252273,
                    }
                    , new Configuration.itemsNpc {
                        ShortName = "hoodie", SkinId = 959641236,
                    }
                    , new Configuration.itemsNpc {
                        ShortName = "shoes.boots", SkinId = 962503020,
                    }
                }
                ;
            }
#region RU
            if (config.settingsSoundNPC.soundAddToCfg) {
                if (config.settingsSoundNPC.heySound.Count == 0) {
                    config.settingsSoundNPC.heySound = new List<string> {
                        "hello_1", "hello_2"
                    }
                    ;
                }
                if (config.settingsSoundNPC.byeSound.Count == 0) {
                    config.settingsSoundNPC.byeSound = new List<string> {
                        "bye_1", "bye_2"
                    }
                    ;
                }
                if (config.settingsSoundNPC.takeQuestSound.Count == 0) {
                    config.settingsSoundNPC.takeQuestSound = new List<string> {
                        "pick_up_quest_1", "pick_up_quest_2"
                    }
                    ;
                }
                if (config.settingsSoundNPC.turnQuestSound.Count == 0) {
                    config.settingsSoundNPC.turnQuestSound = new List<string> {
                        "turn_in_quest_1", "turn_in_quest_2"
                    }
                    ;
                }
                config.settingsSoundNPC.soundAddToCfg = false;
            }
#endregion
#region EN
            //if (config.settingsSoundNPC.soundAddToCfg)
            //{
            //    if (config.settingsSoundNPC.heySound.Count == 0)
            //    {
            //        config.settingsSoundNPC.heySound = new List<string>
            //        {
            //            "hello_1", "hello_2", "hello_3"
            //        };
            //    }
            //    if (config.settingsSoundNPC.byeSound.Count == 0)
            //    {
            //        config.settingsSoundNPC.byeSound = new List<string>
            //        {
            //            "bye_1", "bye_2", "bye_3"
            //        };
            //    }
            //    if (config.settingsSoundNPC.takeQuestSound.Count == 0)
            //    {
            //        config.settingsSoundNPC.takeQuestSound = new List<string>
            //        {
            //            "pick_up_quest"
            //        };
            //    }
            //    if (config.settingsSoundNPC.turnQuestSound.Count == 0)
            //    {
            //        config.settingsSoundNPC.turnQuestSound = new List<string>
            //        {
            //            "turn_in_quest", "turn_in_quest_2"
            //        };
            //    }
            //    config.settingsSoundNPC.soundAddToCfg = false;
            //}
#endregion
        }
        protected override void SaveConfig() {
            Config.WriteObject(config);
        }
        protected override void LoadDefaultConfig() {
            config = new Configuration();
        }
#endregion
#region QuestData
        private class PlayerQuest {
            public Quest parentQuest;
            public ulong UserID;
            public bool Finished;
            public int Count;
            public void AddCount(int amount = 1) {
                Count += amount;
                BasePlayer player = BasePlayer.FindByID(UserID);
                if (parentQuest.Amount <= Count) {
                    Count = parentQuest.Amount;
                    if (player != null && player.IsConnected) {
                        if (Instance.config.settings.SoundEffect) Instance.RunEffect(player, Instance.config.settings.Effect);
                        if (Instance.config.settingsNotify.useNotify && Instance.Notify) Instance.Notify.CallHook("SendNotify", player, Instance.config.settingsNotify.typeNotify, Instance.GetLang("XDQUEST_Finished_QUEST", player.UserIDString, parentQuest.DisplayName));
                        else Instance.SendChat(player, Instance.GetLang("XDQUEST_Finished_QUEST", player.UserIDString, parentQuest.DisplayName));
                        Interface.CallHook("OnQuestCompleted", player, parentQuest.DisplayName);
                    }
                    Finished = true;
                }
                if (Instance.openQuestPlayers.Contains(UserID)) {
                    CuiHelper.DestroyUi(player, MiniQuestList);
                    Instance.OpenMQL_CMD(player);
                }
            }
            public int LeftAmount() => parentQuest.Amount - Count;
        }
        public enum QuestType {
            IQPlagueSkill, IQHeadReward, IQCases, OreBonus, XDChinookIvent, Gather, EntityKill, Craft, Research, Loot, Grade, Swipe, Deploy, PurchaseFromNpc, HackCrate, RecycleItem, Growseedlings, RaidableBases, Fishing
        }
        public enum PrizeType {
            Item, BluePrint, CustomItem, Command
        }
        private class Quest {
            internal class Prize {
                public string nameprize;
                public PrizeType type;
                public string ShortName;
                public int Amount;
                public string Name;
                public ulong SkinID;
                public string Command;
                public string Url;
            }
            public string DisplayName;
            public string Description;
            public string Missions;
            public QuestType QuestType;
            public string Target;
            public int Amount;
            public bool UseRepeat;
            public bool Bring;
            public int Cooldown;
            public List<Prize> PrizeList = new List<Prize>();
        }
#endregion
#region MetodsBuildingAndNpc
        private class Building {
            public string name;
            public float Deg2Rad;
            public Vector3 pos;
        }
        private Dictionary<string, Building> BuildingList = new Dictionary<string, Building> {
            ["1"]
            = new Building {
                name = "QuestHouseChristmas", Deg2Rad = 4.75f, pos = new Vector3(-7.32f, 1.76f, 43.83f)
            }
            , ["2"] = new Building {
                name = "QuestHouse6", Deg2Rad = 5.38f, pos = new Vector3(-6.76f, 1.73f, 46.63f)
            }
            ,
        }
        ;
        void GenerateBuilding() {
            var options = new List<string> {
                "stability", "true", "deployables", "true", "autoheight", "false", "entityowner", "true"
            }
            ;
            Vector3 resultVector = GetResultVector();
            var success = CopyPaste.Call("TryPasteFromVector3", resultVector, config.customPosition.useCustomPos ? (Vector3.zero * Mathf.Deg2Rad).y - config.customPosition.rotation : (monument.transform.rotation.eulerAngles * Mathf.Deg2Rad).y - BuildingList["2"].Deg2Rad, BuildingList["2"].name, options.ToArray());
            if (success is string) {
                PrintWarning(GetLang("XDQUEST_CopyPasteError"));
                return;
            }
            if (config.settings.mapUse) Interface.CallHook("API_CreateMarker", resultVector, "xdquest", 0, 3f, 0.2f, config.settings.nameMarkerMap, config.settings.colorMarker, config.settings.colorOutline);
            if (config.customPosition.useCustomPos) {
                safeZone = new GameObject().AddComponent<SafeZone>();
                safeZone.Activate(resultVector, config.settings.saveZoneRadius);
            }
        }
        private void CrateBox(Vector3 pos) {
            BaseEntity box = GameManager.server.CreateEntity("assets/prefabs/deployable/quarry/fuelstorage.prefab", pos + Vector3.up, Quaternion.identity);
            box.enableSaving = false;
            box.OwnerID = 76561198283599982;
            box.skinID = 1195832261;
            box.Spawn();
            HouseNPC.Add(box);
        }
        private void InitializeNPC(Vector3 pos) {
            npc = GameManager.server.CreateEntity("assets/prefabs/player/player.prefab", pos) as BasePlayer;
            if (npc == null) {
                Interface.Oxide.LogError($"Initializing NPC failed! NPC Component == null #3");
                return;
            }
            npc.userID = config.settingsNpc.userId;
            npc.name = config.settingsNpc.Name;
            npc.displayName = npc.name;
            npc.Spawn();
            npc.SendNetworkUpdate();
            chairNpc.MountPlayer(npc);
            chairNpc.SetFlag(BaseEntity.Flags.Busy, true);
            CrateBox(npc.transform.position);
            if (config.settingsSoundNPC.soundUse) {
                zoneTrigger = new GameObject().AddComponent<ZoneTrigger>();
                zoneTrigger.Activate(pos, 3.2f);
            }
#region NpcWearStart
            if (config.settingsNpc.Wear.Count > 0) for (int i = 0; i < config.settingsNpc.Wear.Count; i++) ItemManager.Create(ItemManager.FindItemDefinition(config.settingsNpc.Wear[i].ShortName), 1, config.settingsNpc.Wear[i].SkinId).MoveToContainer(npc.inventory.containerWear);
#endregion
        }
        private void ClearEnt() {
            IEnumerable<BasePlayer> findplayer = FindMyBot(config.settingsNpc.userId);
            foreach (var player in findplayer) if (player != null) player.KillMessage();
            List<BaseEntity> obj = new List<BaseEntity>();
            Vis.Entities(GetResultVector(), 10f, obj, LayerMask.GetMask("Construction", "Deployable", "Deployed", "Debris", "Default"));
            foreach (BaseEntity item in obj.Where(x => x.OwnerID == 76561198283599982)) {
                if (item == null) continue;
                item.Kill();
            }
            timer.Once(5f, () => {
                GenerateBuilding();
            }
            );
        }
        void OnPasteFinished(List<BaseEntity> pastedEntities, string fileName) {
            if (fileName.ToLower() != BuildingList["2"].name.ToLower()) return;
            try {
                HouseNPC.AddRange(pastedEntities);
                foreach (BaseEntity item in HouseNPC) {
                    if (Light.Contains(item.prefabID)) {
                        item.enableSaving = true;
                        item?.SetFlag(BaseEntity.Flags.Reserved8, true);
                        item?.SetFlag(BaseEntity.Flags.On, true);
                        item?.SendNetworkUpdate();
                    }
                    NeonSign neonSign = item as NeonSign;
                    if (neonSign != null) {
                        neonSign.SetFlag(BaseEntity.Flags.On, true);
                        neonSign.SetFlag(BaseEntity.Flags.Reserved8, true);
                        neonSign.isAnimating = true;
                        neonSign.InvokeRepeating(neonSign.animationLoopAction, 2f, 2f);
                        neonSign.SendNetworkUpdate();
                    }
                    SnowMachine snowMachine = item as SnowMachine;
                    if (snowMachine != null) {
                        snowMachine.SetFlag(BaseEntity.Flags.Reserved8, true);
                        snowMachine.SetFlag(BaseEntity.Flags.Reserved7, false);
                        snowMachine.SetFlag(BaseEntity.Flags.Reserved6, true);
                        snowMachine.SetFlag(BaseEntity.Flags.Reserved5, true);
                    }
                    DecayEntity decayEntety = item as DecayEntity;
                    if (decayEntety != null) {
                        decayEntety.decay = null;
                        decayEntety.decayVariance = 0;
                        decayEntety.ResetUpkeepTime();
                        decayEntety.DecayTouch();
                    }
                    DeployableBoomBox boomBox = item as DeployableBoomBox;
                    if (boomBox != null) {
                        if (config.settings.useRadio) {
                            NextTick(() => {
                                boomBox.BoxController.CurrentRadioIp = config.settings.RadioStation;
                                boomBox.BoxController.ConditionLossRate = 0;
                                boomBox.BoxController.baseEntity.ClientRPC(null, "OnRadioIPChanged", boomBox.BoxController.CurrentRadioIp);
                                if (!boomBox.BoxController.IsOn()) {
                                    boomBox.BoxController.ServerTogglePlay(true);
                                }
                                boomBox.BoxController.baseEntity.SendNetworkUpdate(global : : BasePlayer.NetworkQueue.Update);
                            }
                            );
                        }
                    }
                    BuildingBlock build = item as BuildingBlock;
                    if (build != null) {
                        build.StopBeingDemolishable();
                        build.StopBeingRotatable();
                    }
                    if (item is ComputerStation) {
                        chairNpc = item as ComputerStation;
                        continue;
                    }
                    Door door = item as Door;
                    if (door != null) {
                        door.pickup.enabled = false;
                        door.canTakeLock = false;
                        door.canTakeCloser = false;
                    }
                    item.SetFlag(BaseEntity.Flags.Busy, true);
                    item.SetFlag(BaseEntity.Flags.Locked, true);
                }
                if(chairNpc != null) InitializeNPC(chairNpc.transform.position);
                PrintWarning(GetLang("XDQUEST_CopyPasteSuccessfully"));
            }
            catch (Exception ex) {
                PrintError(GetLang("XDQUEST_BuildingPasteError"));
                Log(ex.InnerException.Message, "LogError");
            }
        }
#endregion
#region Scripts
        private class ZoneTrigger : FacepunchBehaviour {
            private float ZoneRadius;
            private Vector3 Position;
            private SphereCollider sphereCollider;
            private void Awake() {
                gameObject.layer = (int)Layer.Reserved1;
                gameObject.name = "ZoneTrigger1866";
                enabled = false;
            }
            public void Activate(Vector3 pos, float radius) {
                Position = pos;
                ZoneRadius = radius;
                transform.position = Position;
                transform.rotation = new Quaternion();
                UpdateCollider();
                gameObject.SetActive(true);
                enabled = true;
            }
            private void OnTriggerEnter(Collider col) {
                BasePlayer player = col.GetComponentInParent<BasePlayer>();
                if (player != null && !player.IsNpc && player.userID.IsSteamId()) {
                    if (player.IsVisible(Instance.npc.eyes.position)) {
                        int mIndex = Random.Range(0, Instance.config.settingsSoundNPC.heySound.Count);
                        Instance.SoundPlay(Instance.config.settingsSoundNPC.heySound[mIndex]);
                    }
                }
            }
            private void OnTriggerExit(Collider col) {
                BasePlayer player = col.GetComponentInParent<BasePlayer>();
                if (player != null && !player.IsNpc && player.userID.IsSteamId()) {
                    if (player.IsVisible(Instance.npc.eyes.position)) {
                        int mIndex = Random.Range(0, Instance.config.settingsSoundNPC.byeSound.Count);
                        Instance.SoundPlay(Instance.config.settingsSoundNPC.byeSound[mIndex]);
                    }
                    player.SendConsoleCommand("CloseMainUI");
                    if (Instance.openQuestPlayers.Contains(player.userID)) {
                        CuiHelper.DestroyUi(player, MiniQuestList);
                        Instance.OpenMQL_CMD(player);
                    }
                }
            }
            private void OnDestroy() {
                Destroy(gameObject);
                CancelInvoke();
            }
            private void UpdateCollider() {
                sphereCollider = gameObject.GetComponent<SphereCollider>();
                {
                    if (sphereCollider == null) {
                        sphereCollider = gameObject.AddComponent<SphereCollider>();
                        sphereCollider.isTrigger = true;
                        sphereCollider.name = "ZoneTrigger1866";
                    }
                    sphereCollider.radius = ZoneRadius;
                }
            }
        }
        private class SafeZone : MonoBehaviour {
            private Vector3 Position;
            private float Radius;
            private void Awake() {
                gameObject.layer = (int)Layer.Reserved1;
                gameObject.name = "NpcZonesOrRadiation";
                var rigidbody = gameObject.AddComponent<Rigidbody>();
                rigidbody.useGravity = false;
                rigidbody.isKinematic = true;
            }
            public void Activate(Vector3 pos, float radius) {
                Position = pos;
                Radius = radius;
                transform.position = Position;
                UpdateCollider();
                gameObject.SetActive(true);
                enabled = true;
                var safeZone = gameObject.GetComponent<TriggerSafeZone>();
                safeZone = safeZone ?? gameObject.AddComponent<TriggerSafeZone>();
                safeZone.interestLayers = LayerMask.GetMask("Player (Server)");
                safeZone.enabled = true;
            }
            private void OnDestroy() {
                Destroy(gameObject);
            }
            private void UpdateCollider() {
                var sphereCollider = gameObject.GetComponent<SphereCollider>();
                {
                    if (sphereCollider == null) {
                        sphereCollider = gameObject.AddComponent<SphereCollider>();
                        sphereCollider.isTrigger = true;
                    }
                    sphereCollider.radius = Radius;
                }
            }
        }
#endregion
#region Hooks
#region QuestHook
#region Type Upgrade
        object OnStructureUpgrade(BaseCombatEntity entity, BasePlayer player, BuildingGrade.Enum grade) {
            QuestProgress(player, QuestType.Grade, ((int)grade).ToString());
            return null;
        }
#endregion
#region IQPlagueSkill
        void StudySkill(BasePlayer player, string name) => QuestProgress(player, QuestType.IQPlagueSkill, name);
#endregion
#region HeadReward
        void KillHead(BasePlayer player) => QuestProgress(player, QuestType.IQHeadReward);
#endregion
#region IqCase
        void OpenCase(BasePlayer player, string name) => QuestProgress(player, QuestType.IQCases, name);
#endregion
#region OreBonus
        void RadOreGive(BasePlayer player, Item item) => QuestProgress(player, QuestType.OreBonus, item.info.shortname, "", null, item.amount);
#endregion
#region Chinook
        void LootHack(BasePlayer player) => QuestProgress(player, QuestType.XDChinookIvent);
#endregion
#region Gather
        private void OnDispenserGather(ResourceDispenser dispenser, BaseEntity entity, Item item) {
            NextTick(() => {
                BasePlayer player = entity as BasePlayer;
                ;
                if (player != null) QuestProgress(player, QuestType.Gather, item.info.shortname, "", null, item.amount);
            }
            );
        }
        void OnDispenserBonus(ResourceDispenser dispenser, BaseEntity entity, Item item) => OnDispenserGather(dispenser, entity, item);
        void OnCollectiblePickup(Item item, BasePlayer player) => QuestProgress(player, QuestType.Gather, item.info.shortname, "", null, item.amount);
#endregion
#region Craft
        void OnItemCraftFinished(ItemCraftTask task, Item item) => QuestProgress(task.owner, QuestType.Craft, task.blueprint.targetItem.shortname, "", null, item.amount);
#endregion
#region Research
        void OnTechTreeNodeUnlock(Workbench workbench, TechTreeData.NodeInstance node, BasePlayer player) => QuestProgress(player, QuestType.Research, node.itemDef.shortname);
        void OnItemResearch(ResearchTable table, Item targetItem, BasePlayer player) => QuestProgress(player, QuestType.Research, targetItem.info.shortname);
#endregion
#region Deploy
        private void OnEntityBuilt(Planner plan, GameObject go) {
            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, QuestType.Deploy, plan.GetItem().info.shortname);
        }
#endregion
#region Loot
        private static Dictionary<BasePlayer, List<UInt64>> LootersListCarte = new Dictionary<BasePlayer, List<UInt64>>();
        private void OnLootEntity(BasePlayer player, LootContainer entity) {
            if (entity == null || entity.net == null || player == null || entity.OwnerID.IsSteamId()) return;
            if (!LootersListCarte.ContainsKey(player)) LootersListCarte.Add(player, new List<UInt64> {
            }
            );
            UInt64 netId = entity.net.ID;
            if (LootersListCarte[player].Contains(netId)) return;
            QuestProgress(player, QuestType.Loot, "", "", entity.inventory.itemList);
            LootersListCarte[player].Add(netId);
        }
        private void OnLootEntity(BasePlayer player, NPCPlayerCorpse entity) {
            if (entity.OwnerID.IsSteamId() || entity == null) return;
            if (!LootersListCarte.ContainsKey(player)) LootersListCarte.Add(player, new List<UInt64> {
            }
            );
            UInt64 netId = entity.net.ID;
            if (LootersListCarte[player].Contains(netId)) return;
            QuestProgress(player, QuestType.Loot, "", "", entity.containers[0].itemList);
            LootersListCarte[player].Add(netId);
        }
        private void OnContainerDropItems(ItemContainer container) {
            if (container == null) return;
            BaseEntity entity = container.entityOwner;
            if (entity == null) return;
            if (!entity.ShortPrefabName.Contains("barrel")) return;
            foreach (Item lootitem in container.itemList) lootitem.SetFlag(global : : Item.Flag.Placeholder, true);
        }
        void OnItemPickup(Item item, BasePlayer player) {
            if (item == null || !item.HasFlag(global : : Item.Flag.Placeholder)) return;
            item.SetFlag(global : : Item.Flag.Placeholder, false);
            QuestProgress(player, QuestType.Loot, item.info.shortname, item.skin.ToString(), count : item.amount);
        }
#endregion
#region Swipe
        private void OnCardSwipe(CardReader cardReader, Keycard card, BasePlayer player) {
            global : : Item item = card.GetItem();
            if (item != null && card.accessLevel == cardReader.accessLevel && item.conditionNormalized > 0f) {
                QuestProgress(player, QuestType.Swipe, card.GetItem().info.shortname);
            }
        }
#endregion
#region  EntityKill/взорвать/уничтожить что либо
        void OnPlayerDeath(BasePlayer player, HitInfo info) {
            if (player == null || info == null || player.userID < 2147483647) return;
            BasePlayer attacker = info.InitiatorPlayer;
            if (attacker == null) return;
            if (IsFriends(player.userID, attacker.userID) || IsClans(player.UserIDString, attacker.UserIDString) || IsDuel(attacker.userID) || player.userID == attacker.userID) return;
            QuestProgress(player, QuestType.EntityKill, "player");
        }
        void OnEntityDeath(BaseCombatEntity entity, HitInfo info) {
            try {
                if (entity == null || info == null) return;
                string targetName = entity?.ShortPrefabName;
                if (targetName.Contains("corpse") || targetName.Contains("servergibs") || targetName.Contains("player")) return;
                if (targetName == "testridablehorse") {
                    targetName = "horse";
                }
                BasePlayer player = null;
                if (info.InitiatorPlayer != null) player = info.InitiatorPlayer;
                else if (entity.GetComponent<BaseHelicopter>() != null) {
                    PatrolHelicopterAI helicopterAI = entity?.GetComponent<PatrolHelicopterAI>();
                    if (helicopterAI == null) return;
                    player = helicopterAI._targetList[helicopterAI._targetList.Count - 1].ply;
                }
                if (player != null && !player.IsNpc && entity.ToPlayer() != player) {
                    QuestProgress(player, QuestType.EntityKill, targetName.ToLower());
                }
            }
            catch (Exception) {
            }
        }
#endregion
#region (NEW) Покупки у НПС
        void OnNpcGiveSoldItem(NPCVendingMachine machine, Item soldItem, BasePlayer buyer) => QuestProgress(buyer, QuestType.PurchaseFromNpc, soldItem.info.shortname, "", null, soldItem.amount);
#endregion
#region(NEW) Взлом ящика
        void CanHackCrate(BasePlayer player, HackableLockedCrate crate) {
            QuestProgress(player, QuestType.HackCrate, "", "", null);
        }
#endregion
#region (NEW) RecycleItem (Игрок не должен выходить из интерфейса переработчика)
        private Dictionary<uint, BasePlayer> recyclePlayer = new Dictionary<uint, BasePlayer>();
        void OnRecyclerToggle(Recycler recycler, BasePlayer player) {
            if (!recycler.IsOn()) {
                if (recyclePlayer.ContainsKey(recycler.net.ID)) {
                    recyclePlayer.Remove(recycler.net.ID);
                    recyclePlayer.Add(recycler.net.ID, player);
                }
                else recyclePlayer.Add(recycler.net.ID, player);
            }
            else if (recyclePlayer.ContainsKey(recycler.net.ID)) recyclePlayer.Remove(recycler.net.ID);
        }
        void OnRecycleItem(Recycler recycler, Item item) {
            if (recyclePlayer.ContainsKey(recycler.net.ID)) {
                int num2 = 1;
                if (item.amount > 1) num2 = Mathf.CeilToInt(Mathf.Min((float)item.amount, (float)item.info.stackable * 0.1f));
                QuestProgress(recyclePlayer[recycler.net.ID], QuestType.RecycleItem, item.info.shortname, "", null, num2);
            }
        }
#endregion
#region (NEW) Growseedlings
        void OnGrowableGathered(GrowableEntity plant, Item item, BasePlayer player) {
            QuestProgress(player, QuestType
// ... [Code preview truncated due to length. Full source in attached file] ...

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