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

FREE XDQuest : 2.0.5 2.0.5

Нет прав для скачивания
C#:
using Newtonsoft.Json;
using Oxide.Core;
using Rust;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Plugins;
using Network;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries;
using System.Collections;
using System.Text;
namespace Oxide.Plugins {
    [Info("XDQuest", "DezLife", "2.0.5")]
    [Description("Расширенная квест система для вашего сервера!")]
    public class XDQuest : RustPlugin {
#region Var
        private const string AuthorContact = "DezLife#1480 \nvk.com/dezlife";
        private const string filename = "XDQuestHouseNPC";
        private static XDQuest Instance;
        MonumentInfo monument;
        HashSet<Item> ItemForce = new HashSet<Item>();
        private BasePlayer npc;
        private List<BaseEntity> HouseNPC = new List<BaseEntity>();
        private Dictionary<string, string> ImageUI = new Dictionary<string, string>() {
            {
                "MAINFON", "https://i.imgur.com/sV7tvFE.png"
            }
            , {
                "QUESTFON", "https://i.imgur.com/3yfcpYV.png"
            }
            , {
                "DOWNBTN", "https://i.imgur.com/VYdpOFv.png"
            }
            , {
                "UPBTN", "https://i.imgur.com/3E9KNpZ.png"
            }
            , {
                "BluePrint", "https://i.imgur.com/b48U2XA.png"
            }
            , {
                "InProcces", "https://i.imgur.com/IKE6USt.png"
            }
            , {
                "CloseUI", "https://i.imgur.com/7oInHGR.png"
            }
        }
        ;
#region Ref
        [PluginReference]
        Plugin CopyPaste, ImageLibrary, IQChat, Friends, Clans, Battles, Duel;
        public 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);
        }
        public bool IsFriends(ulong userID, ulong targetID) {
            if (Friends) return (bool)Friends?.Call("HasFriend", userID, targetID);
            else return false;
        }
        public bool IsClans(ulong userID, ulong targetID) {
            if (Clans) return (bool)Clans?.Call("HasFriend", userID, targetID);
            else return false;
        }
        public 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;
        }
        public string GetImage(string shortname, ulong skin = 0) => (string)ImageLibrary?.Call("GetImage", shortname, skin);
        public bool AddImage(string url, string shortname, ulong skin = 0) => (bool)ImageLibrary?.Call("AddImage", url, shortname, skin);
        public void SendImage(BasePlayer player, string imageName, ulong imageId = 0) => ImageLibrary?.Call("SendImage", player, imageName, imageId);
#endregion
#endregion
#region Lang
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["QUEST_ACTIVE"]
                = "Your active tasks: {0}", ["NOT_QUEST_ACTIVE"] = "You have no active tasks", ["QUEST_Insufficient_resources"] = "You don't have {0}, you should definitely bring this to Sidorovich", ["QUEST_not_resources"] = "You don't have enough {0}, you need {1}", ["QUEST_ACTIVE_COMPLITE"] = "{0}\nQuests completed!\nDo not forget to hand it over to Sidorovich.", ["NOT_QUEST_ACTIVE_COMPLITE"] = "<size=9>{0}</size>\nLeft: {1}\n{2}", ["AVAILABLE_MISSIONS"] = "<b>AVAILABLE JOBS</b><size=14>({0})</size>", ["ACTIVE_MISSIONS"] = "<b>ACTIVE JOBS</B><size=14>({0})</size>", ["NOT_AVAILABLE_MISSIONS"] = "You have no tasks available :(", ["REWARD_FOR_QUESTIONS"] = "<b>REWARD FOR COMPLETING THE MISSION</b>", ["CAN"] = "can", ["CAN'T"] = "can't", ["absent's"] = "absent", ["QUEST_ACTIVE_LIMIT"] = "You have too much <color=#4286f4>unfinished</color> assignments!", ["QUEST_ACTIVE_COLDOWN"] = "You cannot take this quest at the moment", ["QUEST_took_tasks"] = "You already <color=#4286f4>have taken</color> this task!", ["QUEST_completed_tasks"] = "You already <color=#4286f4>performed</color> this task!", ["QUEST_completed_took"] = "You <color=#4286f4>successfully</color> took the task {0}", ["QUEST_tasks_completed"] = "Thanks, keep your <color=#4286f4>reward</color>!", ["QUEST_no_place"] = "Hey wait, you're everything <color=#4286f4>you won't take</color>, make room!", ["QUEST_did_not_cope"] = "Sorry that you <color=#4286f4>did not cope</color> with the task!\n" + $"Anyway, you can try again!", ["QUEST_done"] = "Performed!", ["QUEST_take"] = "TAKE", ["QUEST_turn"] = "Hand over", ["QUEST_REFUSE"] = "REFUSE", ["QUEST_Finished"] = "You have completed the task: <color=#4286f4>{0}</color>", ["QUEST_DONTREPEAT"] = "You have already completed this quest.!", ["QUEST_target"] = "Need to: {0}\n" + "Re-take {1}\n" + "CD to re-take : {2}", ["QUEST_targetrtho"] = "Need to: {0}\n" + "Progress: {1}/{2}\n" + "Re-take {3}\n" + "CD to re-take : {4}",
            }
            , this);
            lang.RegisterMessages(new Dictionary<string, string> {
                ["QUEST_ACTIVE"]
                = "Ваши активные задачи: {0}", ["NOT_QUEST_ACTIVE"] = "У вас нет активных задач", ["QUEST_Insufficient_resources"] = "У вас нету {0}, нужно обязательно принести это сидоровичу", ["QUEST_not_resources"] = "У вас не достаточно {0},  нужно {1}", ["QUEST_ACTIVE_COMPLITE"] = "{0}\nЗадания выполнено!\nНе забудьте сдать его сидоровичу.", ["NOT_QUEST_ACTIVE_COMPLITE"] = "<size=9>{0}</size>\nПрогресс: {1}/{2}\n{3}", ["AVAILABLE_MISSIONS"] = "<b>ДОСТУПНЫЕ ЗАДАНИЯ</b><size=14>({0})</size>", ["ACTIVE_MISSIONS"] = "<b>АКТИВНЫЕ ЗАДАНИЯ</B><size=14>({0})</size>", ["NOT_AVAILABLE_MISSIONS"] = "У вас нет доступных задач :(", ["REWARD_FOR_QUESTIONS"] = "<b>НАГРАДА ЗА ВЫПОЛНЕНИЯ ЗАДАНИЯ</b>", ["CAN"] = "можно", ["CAN'T"] = "нельзя", ["absent's"] = "отсутствует", ["QUEST_ACTIVE_LIMIT"] = "У тебя слишком много <color=#4286f4>не законченных</color> заданий!", ["QUEST_ACTIVE_COLDOWN"] = "В данный момент вы не можете взять этот квест", ["QUEST_took_tasks"] = "Вы уже <color=#4286f4>взяли</color> это задание!", ["QUEST_completed_tasks"] = "Вы уже <color=#4286f4>выполняли</color> это задание!", ["QUEST_completed_took"] = "Вы <color=#4286f4>успешно</color> взяли задание {0}", ["QUEST_tasks_completed"] = "Спасибо, держи свою <color=#4286f4>награду</color>!", ["QUEST_no_place"] = "Эй, погоди, ты всё <color=#4286f4>не унесёшь</color>, освободи место!", ["QUEST_did_not_cope"] = "Жаль что ты <color=#4286f4>не справился</color> с заданием!\n" + $"В любом случае, ты можешь попробовать ещё раз!", ["QUEST_done"] = "Выполнено!", ["QUEST_take"] = "ВЗЯТЬ", ["QUEST_turn"] = "СДАТЬ", ["QUEST_REFUSE"] = "ОТКАЗАТЬСЯ", ["QUEST_Finished"] = "Вы закончили задание: <color=#4286f4>{0}</color>", ["QUEST_DONTREPEAT"] = "Вы уже выполняли этот квест!", ["QUEST_target"] = "Нужно: {0}\n" + "Повторно брать {1}\n" + "Кд на повторное взятие: {2}", ["QUEST_targetrtho"] = "Нужно: {0}\n" + "Прогресс: {1}/{2}\n" + "Повторно брать {3}\n" + "Кд на повторное взятие: {4}",
            }
            , this, "ru");
        }
#endregion
#region Configuration
        public static Configuration config = new Configuration();
        public class Configuration {
            public class itemsNpc {
                [JsonProperty("ShortName")]
                public string ShortName;
                [JsonProperty("SkinId")]
                public ulong SkinId;
            }
            public class Settings {
                [JsonProperty("Колличевство единовременно взятых квестов")]
                public int questCount;
                [JsonProperty("Голосовое оповещение при выполнении задания")]
                public bool SoundEffect;
                [JsonProperty("Эфект")]
                public string Effect;
                [JsonProperty("Названия файла с квестами")]
                public string questListDataName;
                [JsonProperty("Названия файла с Аудио для NPC(Не менять!!!)")]
                public string audioDataPath;
                [JsonProperty("Команда для открытия квест листа с прогрессом")]
                public string questListProgress;
                [JsonProperty("Идентификатор вашей постройки")]
                public string buildid;
            }
            public class SettingsNpc {
                [JsonProperty("Имя нпс")]
                public string Name;
                [JsonProperty("id npc (От его ид зависит его внешность)")]
                public ulong userId;
                [JsonProperty("Одежда нпс")]
                public List<itemsNpc> Wear = new List<itemsNpc>();
            }
            public class SettingsIQChat {
                [JsonProperty("Префикс в чате")]
                public string prifix;
                [JsonProperty("SteamID - Для аватарки из профиля стим")]
                public string SteamID;
            }
            [JsonProperty("Настройки NPC")]
            public SettingsNpc settingsNpc;
            [JsonProperty("Настройки")]
            public Settings settings;
            [JsonProperty("Настройки IQChat (Если есть)")]
            public SettingsIQChat settingsIQChat;
            public static Configuration GetNewConfiguration() {
                return new Configuration {
                    settingsIQChat = new SettingsIQChat {
                        prifix = "Сидорович:", SteamID = "21"
                    }
                    , settings = new Settings {
                        questCount = 3, SoundEffect = true, Effect = "assets/prefabs/locks/keypad/effects/lock.code.lock.prefab", questListDataName = "Quest", audioDataPath = "Audio", questListProgress = "qlist", buildid = "1"
                    }
                    , settingsNpc = new SettingsNpc {
                        Name = "Сидорович\n", userId = 21, Wear = new List<itemsNpc> {
                            new itemsNpc {
                                ShortName = "pants", SkinId = 960252273,
                            }
                            , new itemsNpc {
                                ShortName = "hoodie", SkinId = 959641236,
                            }
                            , new itemsNpc {
                                ShortName = "shoes.boots", SkinId = 962503020,
                            }
                        }
                    }
                    ,
                }
                ;
            }
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                config = Config.ReadObject<Configuration>();
                if (config == null) LoadDefaultConfig();
            }
            catch {
                PrintWarning("Ошибка чтения конфигурации 'oxide/config/', создаём новую конфигурацию!!");
                LoadDefaultConfig();
            }
            if(config.settings.audioDataPath == null) {
                config.settings.audioDataPath = "Audio";
            }
            if (config.settings.buildid == null) {
                config.settings.buildid = "1";
            }
            if (!BuildingList.ContainsKey(config.settings.buildid)) {
                PrintWarning("Вы указали неверный Идентификатор, Спавн стандартной постройки...");
                config.settings.buildid = "1";
            }
            path = "XDQuest/" + config.settings.audioDataPath;
            LoadDataSound();
            NextTick(SaveConfig);
        }
        protected override void LoadDefaultConfig() => config = Configuration.GetNewConfiguration();
        protected override void SaveConfig() => Config.WriteObject(config, true);
#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) {
                    if (player != null && player.IsConnected) {
                        if (config.settings.SoundEffect) Instance.RunEffect(player, config.settings.Effect);
                        Instance.SendChat(player, Instance.GetLang("QUEST_Finished", player.UserIDString, parentQuest.DisplayName));
                        Interface.CallHook("QuestCompleted", player, Instance.GetLang("QUEST_Finished", player.UserIDString, parentQuest.DisplayName));
                    }
                    Finished = true;
                }
                if (Instance.openQuestPlayers.Contains(UserID)) {
                    CuiHelper.DestroyUi(player, QuestListLAYER);
                    Instance.UI_QuestList(player);
                }
            }
            public int LeftAmount() => parentQuest.Amount - Count;
        }
        public enum QuestType {
            IQPlagueSkill, IQHeadReward, IQCases, OreBonus, XDChinookIvent, Добыть, Убить, Скрафтить, Изучить, Залутать, УлучшитьПостройку, ИспользоватьКарточкуДоступа, установить,
        }
        public enum PrizeType {
            Предмет, Чертёж, КастомПредмет, Команда
        }
        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 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 = "XDQuestHouseNPCNew", Deg2Rad = 4.72f, pos = new Vector3(-3.86f, 3.32f, 43.99f)
            }
            , ["2"] = new Building {
                name = "XDQuestHouseNPCNewYear", Deg2Rad = 4.76f, pos = new Vector3(-3.86f, 3.34f, 43.99f)
            }
        }
        ;
        void GenerateBuilding() {
            ClearEnt();
            Subscribe("OnPasteFinished");
            var options = new List<string> {
                "stability", "true", "deployables", "true", "autoheight", "false", "entityowner", "false"
            }
            ;
            Vector3 resultVector = GetResultVector();
            var success = CopyPaste.Call("TryPasteFromVector3", resultVector, (monument.transform.rotation.eulerAngles * Mathf.Deg2Rad).y - BuildingList[config.settings.buildid].Deg2Rad, BuildingList[config.settings.buildid].name, options.ToArray());
            if (success is string) {
                PrintWarning("Ошибка #1 \nПлагин не будет работать, Обратитесь к разработчику" + AuthorContact);
                Unsubscribe("OnPasteFinished");
                return;
            }
            GravityItemAdd();
            timer.Once(5f, () => {
                CrategravityItems();
                InitializeNPC(resultVector);
            }
            );
        }
        public 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();
            List<BaseChair> chairs = new List<BaseChair>();
            Vis.Entities(npc.transform.position, 2f, chairs);
            foreach (var chair in chairs.Distinct().ToList()) {
                chair.MountPlayer(npc);
                npc.OverrideViewAngles(chair.mountAnchor.transform.rotation.eulerAngles);
                npc.eyes.NetworkUpdate(chair.mountAnchor.transform.rotation);
                npc.ClientRPCPlayer(null, npc, "ForcePositionTo", npc.transform.position);
                chair.SetFlag(BaseEntity.Flags.Busy, true);
                break;
            }
            ZoneTrigger zone = new GameObject().AddComponent<ZoneTrigger>();
            zone.Activate(pos, 4.6f);
#region Одеваем нпс
            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() {
            BasePlayer findplayer = FindMyBot(config.settingsNpc.userId);
            if (findplayer != null) findplayer.KillMessage();
            List<BaseEntity> obj = new List<BaseEntity>();
            Vis.Entities(GetResultVector(), 10f, obj, LayerMask.GetMask("Construction", "Deployable", "Deployed", "Debris"));
            foreach (BaseEntity item in obj?.Where(x => x.OwnerID == 1893562145)) {
                if (item == null) continue;
                item.Kill();
            }
        }
        void OnPasteFinished(List<BaseEntity> pastedEntities) {
            try {
                HouseNPC = pastedEntities;
                foreach (BaseEntity item in HouseNPC) {
                    item.OwnerID = 1893562145;
                    if (item as BuildingBlock) {
                        var build = item as BuildingBlock;
                        build.SetFlag(BaseEntity.Flags.Reserved1, false);
                        build.SetFlag(BaseEntity.Flags.Reserved2, false);
                    }
                    if (item is BaseChair) continue;
                    if (item.name.Contains("woodenbox")) {
                        var box = item as BaseCombatEntity;
                        box.pickup.enabled = false;
                        continue;
                    }
                    else if (item.name.Contains("light") || item.name.Contains("lantern")) {
                        item.enableSaving = true;
                        item.SendNetworkUpdate();
                        item.SetFlag(BaseEntity.Flags.Reserved8, true);
                        item.SetFlag(BaseEntity.Flags.On, true);
                    }
                    item.SetFlag(BaseEntity.Flags.Busy, true);
                    item.SetFlag(BaseEntity.Flags.Locked, true);
                }
                PrintWarning($"Постройка обработана успешно {HouseNPC.Count}");
                Unsubscribe("OnPasteFinished");
            }
            catch (Exception ex) {
                PrintError("Ошибка при загрузке постройки! Подробности в лог файле!!\nОбратитесь к разработчику" + AuthorContact);
                Log(ex.Message, "LogError");
            }
        }
#endregion
#region Hooks
#region QuestHook
#region Type Upgrade
        object OnStructureUpgrade(BaseCombatEntity entity, BasePlayer player, BuildingGrade.Enum grade) {
            List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.УлучшитьПостройку && x.Finished == false).ToList();
            if (playerQuests == null || playerQuests.Count == 0) return null;
            for (int i = 0; i < playerQuests.Count; i++) {
                if ((int)grade == Convert.ToInt16(playerQuests[i].parentQuest.Target)) {
                    playerQuests[i].AddCount();
                }
            }
            return null;
        }
#endregion
#region IQPlagueSkill
        void StudySkill(BasePlayer player, string name) {
            List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.IQPlagueSkill && x.Finished == false).ToList();
            if (playerQuests == null || playerQuests.Count == 0) return;
            for (int i = 0; i < playerQuests.Count; i++) {
                if (playerQuests[i].parentQuest.Target == name || playerQuests[i].parentQuest.Target == "0") {
                    playerQuests[i].AddCount();
                }
            }
        }
#endregion
#region HeadReward
        void KillHead(BasePlayer player) {
            List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.IQHeadReward && x.Finished == false).ToList();
            if (playerQuests == null || playerQuests.Count == 0) return;
            for (int i = 0; i < playerQuests.Count; i++) {
                playerQuests[i].AddCount();
            }
        }
#endregion
#region IqCase
        void OpenCase(BasePlayer player, string name) {
            List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.IQCases && x.Finished == false).ToList();
            if (playerQuests == null || playerQuests.Count == 0) return;
            for (int i = 0; i < playerQuests.Count; i++) {
                if (playerQuests[i].parentQuest.Target == name || playerQuests[i].parentQuest.Target == "0") {
                    playerQuests[i].AddCount();
                }
            }
        }
#endregion
#region OreBonus
        void RadOreGive(BasePlayer player, Item item) {
            List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.OreBonus && x.Finished == false).ToList();
            if (playerQuests == null || playerQuests.Count == 0) return;
            for (int i = 0; i < playerQuests.Count; i++) {
                if (playerQuests[i].parentQuest.Target == item.info.shortname || playerQuests[i].parentQuest.Target == "0") {
                    playerQuests[i].AddCount(item.amount);
                }
            }
        }
#endregion
#region Chinook
        void LootHack(BasePlayer player) {
            List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.XDChinookIvent && x.Finished == false).ToList();
            if (playerQuests == null || playerQuests.Count == 0) return;
            for (int i = 0; i < playerQuests.Count; i++) {
                playerQuests[i].AddCount();
            }
        }
#endregion
#region Добыть
        private void OnDispenserGather(ResourceDispenser dispenser, BaseEntity entity, Item item) {
            NextTick(() => {
                BasePlayer player;
                if (entity is BasePlayer) {
                    player = entity as BasePlayer;
                    List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.Добыть && x.Finished == false).ToList();
                    if (playerQuests == null || playerQuests.Count == 0) return;
                    for (int i = 0; i < playerQuests.Count; i++) {
                        if (item.info.shortname.Contains(playerQuests[i].parentQuest.Target)) {
                            playerQuests[i].AddCount(item.amount);
                        }
                    }
                }
            }
            );
        }
        void OnDispenserBonus(ResourceDispenser dispenser, BaseEntity entity, Item item) => OnDispenserGather(dispenser, entity, item);
        void OnCollectiblePickup(Item item, BasePlayer player) {
            List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.Добыть && x.Finished == false).ToList();
            if (playerQuests == null || playerQuests.Count == 0) return;
            for (int i = 0; i < playerQuests.Count; i++) {
                if (item.info.shortname.Contains(playerQuests[i].parentQuest.Target)) {
                    playerQuests[i].AddCount(item.amount);
                }
            }
        }
#endregion
#region Скрафтить
        void OnItemCraftFinished(ItemCraftTask task, Item item) {
            var player = task.owner;
            List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.Скрафтить && x.Finished == false).ToList();
            if (playerQuests == null || playerQuests.Count == 0) return;
            for (int i = 0; i < playerQuests.Count; i++) {
                if (task.blueprint.targetItem.shortname.Contains(playerQuests[i].parentQuest.Target)) {
                    playerQuests[i].AddCount(item.amount);
                }
            }
        }
#endregion
#region Изучить
        void OnItemResearch(ResearchTable table, Item targetItem, BasePlayer player) {
            List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.Изучить && x.Finished == false).ToList();
            if (playerQuests == null || playerQuests.Count == 0) return;
            for (int i = 0; i < playerQuests.Count; i++) {
                if (targetItem.info.shortname.Contains(playerQuests[i].parentQuest.Target)) {
                    playerQuests[i].AddCount();
                }
            }
        }
#endregion
#region установить
        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) return;
            if (ent.skinID == 11543256361) return;
            List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.установить && x.Finished == false).ToList();
            if (playerQuests == null || playerQuests.Count == 0) return;
            for (int i = 0; i < playerQuests.Count; i++) {
                if (plan.GetItem().info.shortname.Contains(playerQuests[i].parentQuest.Target)) {
                    playerQuests[i].AddCount();
                }
            }
        }
        object CanPickupEntity(BasePlayer player, BaseCombatEntity entity) {
            List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.установить && x.Finished == false).ToList();
            if (playerQuests == null || playerQuests.Count == 0) return null;
            for (int i = 0; i < playerQuests.Count; i++) {
                if (entity.pickup.itemTarget.shortname.Contains(playerQuests[i].parentQuest.Target)) {
                    entity.skinID = 11543256361;
                }
            }
            return null;
        }
#endregion
#region Залутать
        private void OnLootEntity(BasePlayer player, LootContainer entity) {
            if (entity.OwnerID == 133722822222222 || entity.OwnerID >= 7656000000 || entity == null) return;
            List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.Залутать && x.Finished == false).ToList();
            if (playerQuests == null || playerQuests.Count == 0) return;
            for (int i = 0; i < playerQuests.Count; i++) {
                for (int u = 0; u < entity.inventory.itemList.Count();
                u++) {
                    if (entity.inventory.itemList[u].info.shortname.Contains(playerQuests[i].parentQuest.Target)) playerQuests[i].AddCount(entity.inventory.itemList[u].amount);
                }
            }
            entity.OwnerID = 133722822222222;
        }
        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);
        }
        object OnItemPickup(Item item, BasePlayer player) {
            if (item == null) return null;
            if (!item.HasFlag(global : : Item.Flag.Placeholder)) return null;
            item.SetFlag(global : : Item.Flag.Placeholder, false);
            List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.Залутать && x.Finished == false).ToList();
            if (playerQuests == null || playerQuests.Count == 0) return null;
            for (int i = 0; i < playerQuests.Count; i++) {
                if (item.info.shortname.Contains(playerQuests[i].parentQuest.Target)) playerQuests[i].AddCount(item.amount);
            }
            return null;
        }
#endregion
#region Использовать карточку доступа
        private void OnCardSwipe(CardReader cardReader, Keycard card, BasePlayer player) {
            List<PlayerQuest> playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.ИспользоватьКарточкуДоступа && x.Finished == false).ToList();
            if (playerQuests == null || playerQuests.Count == 0) return;
            for (int i = 0; i < playerQuests.Count; i++) {
                if (card.GetItem().info.shortname.Contains(playerQuests[i].parentQuest.Target)) {
                    playerQuests[i].AddCount();
                }
            }
        }
#endregion
#region  Убить/взорвать/уничтожить что либо
        void OnEntityDeath(BaseCombatEntity entity, HitInfo info) {
            try {
                if (entity == null || info == null) return;
                List<PlayerQuest> playerQuests = null;
                string entname = entity?.ShortPrefabName;
                if (entname == "testridablehorse") {
                    entname = "horse";
                }
                if (entname.Contains("servergibs")) return;
                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) {
                    if (entity.ToPlayer() != null && entity.ToPlayer() == player) return;
                    if (entity.ToPlayer() != null) {
                        if (IsFriends(player.userID, entity.ToPlayer().userID)) return;
                        if (IsClans(player.userID, entity.ToPlayer().userID)) return;
                        if (IsDuel(player.userID)) return;
                    }
                    playerQuests = storedData.players[player.userID].PlayerQuestsAll.Values.Where(x => x.parentQuest.QuestType == QuestType.Убить && x.Finished == false).ToList();
                    if (playerQuests == null || playerQuests.Count == 0) return;
                    for (int i = 0; i < playerQuests.Count; i++) {
                        if (entity.PrefabName.Contains(playerQuests[i].parentQuest.Target)) {
                            playerQuests[i].AddCount();
                        }
                    }
                }
            }
            catch (Exception ex) {
            }
        }
        void OnEntityTakeDamage(BaseCombatEntity victim, HitInfo info) {
            try {
                if (info.damageTypes.Has(Rust.DamageType.Decay)) {
                    if (victim?.OwnerID == 1893562145) {
                        info.damageTypes.Scale(DamageType.Decay, 0);
                    }
                }
            }
            catch (NullReferenceException) {
            }
        }
#endregion
#endregion
        object CanLootEntity(BasePlayer player, StorageContainer container) {
            if (container.skinID == 1195832261) {
                UI_DrawInterface(player);
                return false;
            }
            return null;
        }
        object CanAffordUpgrade(BasePlayer player, BuildingBlock block, BuildingGrade.Enum grade) {
            if (block.OwnerID == 1893562145) return false;
            else return null;
        }
        void Init() {
            LoadDataPlayer();
            LoadDataQuestList(ref QuestList);
            Unsubscribe("OnPasteFinished");
        }
        private void OnServerInitialized() {
            monument = TerrainMeta.Path.Monuments.FirstOrDefault(p => p.name.ToLower() == "assets/bundled/prefabs/autospawn/monument/medium/compound.prefab");
            Instance = this;
            if (!CopyPaste) {
                PrintError("Проверьте установлен ли у вас плагин 'CopyPaste'");
                Interface.Oxide.UnloadPlugin(Name);
                return;
            }
            else if (CopyPaste.Version < new VersionNumber(4, 1, 26)) {
                PrintError("У вас старая версия CopyPaste!\nПожалуйста обновите плагин до последней версии (4.1.26 или выше) - https://umod.org/plugins/copy-paste");
                Interface.Oxide.UnloadPlugin(Name);
                return;
            }
            if (monument == null) {
                PrintError("Походу у вас отсутствует 'Город НПС' !\nПожалуйста обратитесь к разработчику" + AuthorContact);
                Interface.Oxide.UnloadPlugin(Name);
                return;
            }
            cmd.AddChatCommand(config.settings.questListProgress, this, nameof(UI_QuestList));
            ServerMgr.Instance.StartCoroutine(DownloadImages());
            foreach (var player in BasePlayer.activePlayerList) OnPlayerConnected(player);
            LoadDataCopyPaste();
        }
        void OnPlayerConnected(BasePlayer player) {
            if (!storedData.players.ContainsKey(player.userID)) {
                storedData.players.Add(player.userID, new PlayerData());
            }
            else {
                foreach (var item in storedData.players[player.userID].PlayerQuestsAll) {
                    var curentQuest = QuestList.FirstOrDefault(p => p.Value.DisplayName == item.Value.parentQuest.DisplayName);
                    if(curentQuest.Value == null) {
                        NextTick(() => {
                            storedData.players[player.userID].PlayerQuestsAll.Remove(item.Key);
                        }
                        );
                    }
                }
            }
            foreach (var item in ImageUI) SendImage(player, item.Key);
            PlayersTime.Add(player.userID, null);
        }
        private void OnPlayerDisconnected(BasePlayer d) {
            if (openQuestPlayers.Contains(d.userID)) openQuestPlayers.Remove(d.userID);
            if (PlayersTime.ContainsKey(d.userID)) {
                if (PlayersTime[d.userID] != null) ServerMgr.Instance.StopCoroutine(PlayersTime[d.userID]);
                PlayersTime.Remove(d.userID);
            }
        }
        void Unload() {
            SaveData();
            DestroyAll<ZoneTrigger>();
            for (int i = 0; i < HouseNPC.Count; i++) {
                if (!HouseNPC[i].IsDestroyed) HouseNPC[i]?.Kill();
            }
            npc?.KillMessage();
            foreach (var items in ItemForce) items?.RemoveFromWorld();
            foreach(BasePlayer p in BasePlayer.activePlayerList) {
                if (PlayersTime.ContainsKey(p.userID)) {
                    if(PlayersTime[p.userID] != null) ServerMgr.Instance.StopCoroutine(PlayersTime[p.userID]);
                    PlayersTime.Remove(p.userID);
                }
                CuiHelper.DestroyUi(p, Layers);
                CuiHelper.DestroyUi(p, QuestListLAYER);
            }
            ServerMgr.Instance.StopCoroutine(DownloadImages());
        }
#endregion
#region Летающии итемы
        public class GravityItem {
            public string Shortname;
            public Vector3 vector;
            public Quaternion quaternion;
        }
        List<GravityItem> gravityItems = new List<GravityItem>();
        private void GravityItemAdd() {
            gravityItems.Add(new GravityItem {
                Shortname = "map", vector = monument.transform.position + monument.transform.rotation * new Vector3(-4.96f, 3.32f, 46.66f), quaternion = new Quaternion(1.99f, 0.0f, 0, 2),
            }
            );
            gravityItems.Add(new GravityItem {
                Shortname = "rifle.ak", vector = monument.transform.position + monument.transform.rotation * new Vector3(-5.56f, 2.68f, 44.95f), quaternion = new Quaternion(0f, -1.0f, 0, 2),
            }
            );
            gravityItems.Add(new GravityItem {
                Shortname = "targeting.computer", vector = monument.transform.position + monument.transform.rotation * new Vector3(-5.73f, 2.68f, 46.15f), quaternion = new Quaternion(0, -1.39f, 0, 2),
            }
            );
        }
        public void CrategravityItems() {
            for (int i = 0; i < gravityItems.Count; i++) {
                Item Item = ItemManager.CreateByName(gravityItems[i].Shortname, 1);
                Item.Drop(gravityItems[i].vector, Vector3.up, monument.transform.rotation * gravityItems[i].quaternion);
                var Items = Item.GetWorldEntity() as DroppedItem;
                Items.allowPickup = false;
                Items.CancelInvoke(Items.IdleDestroy);
                var rigidbody = Item.GetWorldEntity().GetComponent<Rigidbody>();
                rigidbody.useGravity = false;
                rigidbody.isKinematic = true;
                ItemForce.Add(Item);
            }
        }
#endregion
#region TriggerNpc
        System.Random rnd = new System.Random();
        private class ZoneTrigger : MonoBehaviour {
            private float ZoneRadius;
            private Vector3 Position;
            private SphereCollider sphereCollider;
            private void Awake() {
                gameObject.layer = (int)Layer.Reserved1;
                gameObject.name = "ZoneTrigger";
                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) {
                    int mIndex = Instance.rnd.Next(Instance._Data.Hey.Length);
                    Instance.API_NPC_SendToAll(Instance._Data.Hey[mIndex]);
                }
            }
            private void OnTriggerExit(Collider col) {
                BasePlayer player = col.GetComponentInParent<BasePlayer>();
                if (player != null) {
                    int mIndex = Instance.rnd.Next(Instance._Data.Bye.Length);
                    Instance.API_NPC_SendToAll(Instance._Data.Bye[mIndex]);
                    player.SendConsoleCommand("Close_Layer");
                }
            }
            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 = "ZoneTrigger";
                    }
                    sphereCollider.radius = ZoneRadius;
                }
            }
        }
#endregion
#region SoundNpc
        public class AudioData {
            public String Name;
            public Single Length = 0;
            public List<VoicePacket> VoicePacketList = new List<VoicePacket>();
            public class VoicePacket {
                public Single TimeOffset;
                public Byte[] Stream;
            }
        }
        public class BotSpeakerData {
            public Dictionary<string, AudioData> AudioClips = new Dictionary<string, AudioData>();
            public string[] Hey;
            public string[] Bye;
        }
        public string path = string.Empty;
        private BotSpeakerData _Data;
        private DynamicConfigFile DataFile;
        private void LoadDataSound() {
            if(String.IsNullOrWhiteSpace(path)) {
                PrintError("Ошибка при загрузке звуков! Плагин будет перезагружен " + AuthorContact);
                return;
            }
            DataFile = Interface.Oxide.DataFileSystem.GetFile(path);
            if (Interface.GetMod().DataFileSystem.ReadObject<BotSpeakerData>(path).AudioClips.Count == 0) {
                PrintWarning("Загрузка звуков для NPC...");
                webrequest.Enqueue($"http://utilite.skyplugins.ru/xdquest/{config.settings.audioDataPath}.json", null, (i, s) => {
                    if (i == 200) WriteToData(s);
                    else {
                        PrintError("Ошибка при загрузке звуков!\nОбратитесь к разработчику " + AuthorContact);
                        Log(i.ToString(), "LogError");
                    }
                }
                , this, RequestMethod.GET);
                ;
            }
            _Data = DataFile.ReadObject<BotSpeakerData>();
        }
        void WriteToData(string calback) {
            _Data = JsonConvert.DeserializeObject<BotSpeakerData>(calback);
            DataFile.WriteObject(_Data);
        }
        public HashSet<uint> BotAlerts = new HashSet<uint>();
        void API_NPC_SendToAll(string clipName) {
            try {
                if (BotAlerts.Contains(npc.net.ID)) return;
                else BotAlerts.Add(npc.net.ID);
                AudioData audio;
                if (_Data.AudioClips.TryGetValue(clipName, out audio)) {
                    var clip = _Data.AudioClips[clipName];
                    timer.Once(clip.Length, () => BotAlerts.Remove(npc.net.ID));
                    audio.VoicePacketList.ForEach(packet => {
                        timer.Once(packet.TimeOffset, () => {
                            if (Net.sv.write.Start()) {
                                Net.sv.write.PacketID(Message.Type.VoiceData);
                                Net.sv.write.UInt32(npc.net.ID);
                                Net.sv.write.BytesWithSize(packet.Stream);
                                var write = Net.sv.write;
                                var sendInfo = new SendInfo() {
                                    connections = BasePlayer.activePlayerList.Select(player => player.Connection).ToList(), priority = Priority.Immediate
                                }
                                ;
                                write.Send(sendInfo);
                            }
                        }
                        );
                    }
                    );
                }
            }
            catch(NullReferenceException ex) {
                PrintError($"Ошибка загрузки звуков! Попробуйте перезагрузить плагин удалив в дате файли {config.settings.audioDataPath}\nИли свяжитесь с разработчиком + {AuthorContact}");
            }
        }
#endregion
#region HelpMetods
        void RunEffect(BasePlayer player, string path) {
            Effect effect = new Effect();
            effect.Init(Effect.Type.Generic, player.transform.position, player.transform.forward, (Connection)null);
            effect.pooledString = path;
            EffectNetwork.Send(effect, player.net.connection);
        }
        public static class TimeHelper {
            public static string FormatTime(TimeSpan time, int maxSubstr = 5, string language = "ru") {
                string result = string.Empty;
                switch (language) {
                    case "ru" : int i = 0;
                    if (time.Days != 0 && i < maxSubstr) {
                        if (!string.IsNullOrEmpty(result)) result += " ";
                        result += $"{Format(time.Days, "д", "д", "д")}";
                        i++;
                    }
                    if (time.Hours != 0 && i < maxSubstr) {
                        if (!string.IsNullOrEmpty(result)) result += " ";
                        result += $"{Format(time.Hours, "ч", "ч", "ч")}";
                        i++;
                    }
                    if (time.Minutes != 0 && i < maxSubstr) {
                        if (!string.IsNullOrEmpty(result)) result += " ";
                        result += $"{Format(time.Minutes, "м", "м", "м")}";
                        i++;
                    }
                    if (time.Days == 0) {
                        if (time.Seconds != 0 && i < maxSubstr) {
                            if (!string.IsNullOrEmpty(result)) result += " ";
                            result += $"{Format(time.Seconds, "с", "с", "с")}";
                            i++;
                        }
                    }
                    break;
                    case "en" : result = string.Format("{0}{1}{2}{3}", time.Duration().Days > 0 ? $"{time.Days:0} day{(time.Days == 1 ? String.Empty : "s")}, " : string.Empty, time.Duration().Hours > 0 ? $"{time.Hours:0} hour{(time.Hours == 1 ? String.Empty : "s")}, " : string.Empty, time.Duration().Minutes > 0 ? $"{time.Minutes:0} minute{(time.Minutes == 1 ? String.Empty : "s")}, " : string.Empty, time.Duration().Seconds > 0 ? $"{time.Seconds:0} second{(time.Seconds == 1 ? String.Empty : "s")}" : string.Empty);
                    if (result.EndsWith(", ")) result = result.Substring(0, result.Length - 2);
                    if (string.IsNullOrEmpty(result)) result = "0 seconds";
                    break;
                }
                return result;
            }
            private static string Format(int units, string form1, string form2, string form3) {
                var tmp = units % 10;
                if (units >= 5 && units <= 20 || tmp >= 5 && tmp <= 9) return $"{units}{form1}";
                if (tmp >= 2 && tmp <= 4) return $"{units}{form2}";
             
// ... [Code preview truncated due to length. Full source in attached file] ...

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