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

FREE QuestSystem : 3.2.1 3.2.1

Нет прав для скачивания
C#:
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Plugins.SignArtistClasses;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using UnityEngine;
using Oxide.Core.Plugins;
using Color = UnityEngine.Color;
using System.Globalization;
using Oxide.Game.Rust.Cui;
using ProtoBuf;
using ConVar;
using Oxide.Core.Configuration;
namespace Oxide.Plugins {
    [Info("QuestSystem", "https://topplugin.ru/", "3.2.1")]
    public class QuestSystem : RustPlugin {
        public static QuestSystem instance;
        [PluginReference]
        Plugin IQChat, RustMap;
#region eNums
        private enum QuestType {
            убить, добыть, скрафтить, найти, улучшить
        }
#endregion
#region Classes
        private class Quest {
            internal class Prize {
                [JsonProperty("Это кастом предмет ? (Если это обычный предмет ставим false)")]
                public bool CustomItem;
                [JsonProperty("Отображаемое имя (Для кастом)")]
                public string DisplayName;
                [JsonProperty("Skin id (Для кастом но можно и для обычного предмета чтоб дать ему скин)")]
                public ulong Skin;
                [JsonProperty("Shortname выдаваемого предмета")]
                public string Shortname;
                [JsonProperty("количество")]
                public int Amount;
                [JsonProperty("Ссылка на картинку (Если используете команду для выдачи то обязательно!)")]
                public string ExternalURL;
                [JsonProperty("Команда")]
                public string Command;
            }
            [JsonProperty("Названия квеста")]
            public string DisplayName;
            [JsonProperty("Описания")]
            public string Description;
            [JsonProperty("Кд на повторное взятия данного квеста (Если не нужно ставим 0)")]
            public float Cooldown;
            [JsonProperty("Тип квеста (0 - убить, 1 - добыть, 2 - скрафтить, 3 - найти, 4 - улучшить)")]
            public QuestType QuestType;
            [JsonProperty("То чего добыть (На русском)")]
            public string NiceTarget;
            [JsonProperty("В зависимости от квеста.Если убить человека то player.Если добыть дерева то wood; Если это улучшения то 1 - дерево, 2 - камень и тд")]
            public string Target;
            [JsonProperty("Количевство")]
            public int Amount;
            [JsonProperty("Настройка награды")]
            public List<Prize> PrizeList = new List<Prize>();
            public List<ulong> FinishedPlayers = new List<ulong>();
        }
        private class PlayerQuest {
            public Quest parentQuest;
            public ulong UserID;
            public bool Finished;
            public int Count;
            public void AddCount(int amount = 1) {
                Count += amount;
                if (parentQuest.Amount <= Count) {
                    BasePlayer player = BasePlayer.FindByID(UserID);
                    if (player != null && player.IsConnected) {
                        if (config.SoundEff) instance.RunEffect(player, config.SoundEffPath);
                        instance.SendChat(instance.lang.GetMessage("QUEST", instance, player.UserIDString), String.Format(instance.lang.GetMessage("QUEST_Finished", instance, player.UserIDString), parentQuest.DisplayName), player);
                    }
                    Finished = true;
                }
            }
            public int LeftAmount() => parentQuest.Amount - Count;
        }
#endregion
#region Lang
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["QUEST_ACTIVE"]
                = "<size=16>Your active tasks:</ size>", ["QUEST"] = "<size=16>Tasks:</size>", ["QUEST_ACTIVE_comp"] = "You <color=#4286f4>are absent</color> active tasks, take them to the city!", ["QUEST_ACTIVE_PROGRESS"] = "You can <color=#4286f4>to complete</color> the task!", ["QUEST_ACTIVE_PROGRESS_GO"] = "Left: {0} {1} {2}\n", ["QUEST_ACTIVE_LIMIT"] = "You have too much <color=#4286f4>not finished</color> tasks!", ["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 hold your <color=#4286f4>reward</color>!", ["QUEST_no_place"] = "Hey wait you everything <color=#4286f4>you will not carry away</color>, make room!", ["QUEST_did_not_cope"] = "Sorry you <color=#4286f4>did not cope</color> with the task!\n" + $"Anyway, you can try again!", ["QUEST_back"] = "FORWARD", ["QUEST_next"] = "BACK", ["QUEST_prize"] = "REWARD FOR PERFORMANCE OF THE TASK", ["QUEST_done"] = "DONE", ["QUEST_take"] = "TAKE", ["QUEST_turn"] = "FOR RENT", ["QUEST_REFUSE"] = "REFUSE", ["QUEST_Finished"] = "You have completed the task: <color=#4286f4>{0}</color>",
            }
            , this);
            lang.RegisterMessages(new Dictionary<string, string> {
                ["QUEST_ACTIVE"]
                = "<size=16>Ваши активные задачи:</size>", ["QUEST"] = "<size=16>Задания:</size>", ["QUEST_ACTIVE_comp"] = "У вас <color=#4286f4>отсутствуют</color> активные задачи, возьмите их в городе!", ["QUEST_ACTIVE_PROGRESS"] = "Вы можете <color=#4286f4>завершить</color> задачу!", ["QUEST_ACTIVE_PROGRESS_GO"] = "Осталось: {0} {1} {2}\n", ["QUEST_ACTIVE_LIMIT"] = "У тебя слишком много <color=#4286f4>не законченных</color> заданий!", ["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_back"] = "ВПЕРЕД", ["QUEST_next"] = "НАЗАД", ["QUEST_prize"] = "НАГРАДА ЗА ВЫПОЛНЕНИЕ ЗАДАНИЯ", ["QUEST_done"] = "ГОТОВО", ["QUEST_take"] = "ВЗЯТЬ", ["QUEST_turn"] = "СДАТЬ", ["QUEST_REFUSE"] = "ОТКАЗАТЬСЯ", ["QUEST_Finished"] = "Вы закончили задание: <color=#4286f4>{0}</color>",
            }
            , this, "ru");
        }
#endregion
#region Configuration
        private static Configuration config = new Configuration();
        private class Configuration {
            [JsonProperty("Можно ли повторно брать квесты ?")]
            public bool QuestGo;
            [JsonProperty("Картинка для доски заданий (Желательный размер 256 на 128)")]
            public string ImageURL;
            [JsonProperty("Максимум квестов которых игрок сможет взять за раз")]
            public int MaxQuestAmount;
            [JsonProperty("Оповестить игрока звуковым оповещением о том что он выполнил квест?")]
            public bool SoundEff;
            [JsonProperty("Эфект для проигрования")]
            public string SoundEffPath;
            [JsonProperty("Делать маркер на карте j?")]
            public bool MapMarkers;
            [JsonProperty("Сбрасывать прогрес квестов у игроков во время вайпа:?")]
            public bool WipeData;
            [JsonProperty("Включить прогресс бар для игроков ?")]
            public bool ProgressBar;
            [JsonProperty("Цвет кнопок (Вперед/Назад)")]
            public string ColorButton;
            public static Configuration GetNewConfiguration() {
                return new Configuration {
                    QuestGo = true, ImageURL = "https://i.imgur.com/Zd10HwE.png", MaxQuestAmount = 3, SoundEff = true, SoundEffPath = "assets/prefabs/locks/keypad/effects/lock.code.unlock.prefab", MapMarkers = false, WipeData = true, ProgressBar = true, ColorButton = "#5ede89d1"
                }
                ;
            }
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                config = Config.ReadObject<Configuration>();
                if (config == null) LoadDefaultConfig();
            }
            catch {
                PrintWarning("Ошибка #153" + $"чтения конфигурации 'oxide/config/{Name}', создаём новую конфигурацию!!");
                LoadDefaultConfig();
            }
            NextTick(SaveConfig);
        }
        protected override void LoadDefaultConfig() => config = Configuration.GetNewConfiguration();
        protected override void SaveConfig() => Config.WriteObject(config);
#endregion
#region Variables
        [PluginReference]
        private Plugin ImageLibrary;
        private BaseEntity Sign = null;
        private List<Quest> QuestList = new List<Quest> {
            {
                new Quest {
                    DisplayName = "Тупая железяка!!", Description = "Как же меня достал этот Танк,я не могу ходить в космодром!\nУничтожь танк и приходи за наградой", Cooldown = 0f, QuestType = QuestType.убить, NiceTarget = "танк", Target = "bradleyapc", Amount = 1, PrizeList = new List<Quest.Prize> {
                        new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "rifle.l96", Amount = 1, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "weapon.mod.small.scope", Amount = 1, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "jackhammer", Amount = 1, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "", Amount = 1, ExternalURL = "https://i.imgur.com/9OJhuKj.png", Command = "emerald.give %STEAMID% Рубин 15",
                        }
                        ,
                    }
                }
            }
            , {
                new Quest {
                    DisplayName = "Нужно срочно отстроить дом!", Description = "Нам нужно где то складывать свои ресурсы!\n Добудь 1000 камня и возвращайся за наградой", Cooldown = 7200f, QuestType = QuestType.добыть, NiceTarget = "камня", Target = "stones", Amount = 1000, PrizeList = new List<Quest.Prize> {
                        new Quest.Prize {
                            CustomItem = true, DisplayName = "Радиактивная сера", Skin = 1681986132, Shortname = "glue", Amount = 10, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "supply.signal", Amount = 1, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "door.hinged.toptier", Amount = 1, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "", Amount = 1, ExternalURL = "https://i.imgur.com/9OJhuKj.png", Command = "emerald.give %STEAMID% Рубин 25",
                        }
                        ,
                    }
                }
            }
            , {
                new Quest {
                    DisplayName = "Хммм...Нужно сделать гараж для мини-коптера!", Description = "Нужно побольше места для коптеров\nСкрафти 1 гаражных дверей", Cooldown = 30f, QuestType = QuestType.скрафтить, NiceTarget = "гаражных дверей", Target = "wall.frame.garagedoor", Amount = 1, PrizeList = new List<Quest.Prize> {
                        new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "", Amount = 1, ExternalURL = "https://i.imgur.com/PoeTa16.png", Command = "give_minicopter %STEAMID%",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "floor.ladder.hatch", Amount = 1, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Shortname = "keycard_blue", Amount = 2, ExternalURL = "", Command = "",
                        }
                        ,
                    }
                }
            }
            , {
                new Quest {
                    DisplayName = "Мне нужно больше изучений!", Description = "Мне нужно изучить множество вещей,но у меня не хватает скрапа\nНайди 100 скрапа и приходи за наградой!", Cooldown = 30f, QuestType = QuestType.найти, NiceTarget = "скрап(-а)", Target = "scrap", Amount = 100, PrizeList = new List<Quest.Prize> {
                        new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "smg.thompson", Amount = 1, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "ammo.pistol.fire", Amount = 64, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "", Amount = 1, ExternalURL = "https://i.imgur.com/9OJhuKj.png", Command = "emerald.give %STEAMID% Рубин 15",
                        }
                        ,
                    }
                }
            }
            , {
                new Quest {
                    DisplayName = "Нужно укрепить свою строения в камень!", Description = "Улучши 15 разных построек в камень", Cooldown = 30f, QuestType = QuestType.улучшить, NiceTarget = "раз в камень", Target = "2", Amount = 15, PrizeList = new List<Quest.Prize> {
                        new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "gates.external.high.stone", Amount = 1, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "bed", Amount = 1, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "furnace.large", Amount = 1, ExternalURL = "", Command = "",
                        }
                        ,
                    }
                }
            }
            , {
                new Quest {
                    DisplayName = "Мой дом, моя крепость", Description = "Нужно лучше защитить свою базу\nСкрафти 10 заборов", Cooldown = 30f, QuestType = QuestType.скрафтить, NiceTarget = "забор(-ов)", Target = "wall.external.high.stone", Amount = 10, PrizeList = new List<Quest.Prize> {
                        new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "wall.window.glass.reinforced", Amount = 3, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "metal.fragments", Amount = 5000, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "", Amount = 1, ExternalURL = "https://i.imgur.com/JnPNvJi.png", Command = "givetool %STEAMID% pickaxe",
                        }
                        ,
                    }
                }
            }
            , {
                new Quest {
                    DisplayName = "Мои любимые часы", Description = "Мои любимые часы барахлят,опять эти шестеренки..\nНайди 40 шестеренок и приходи за наградой!", Cooldown = 30f, QuestType = QuestType.найти, NiceTarget = "шестеренка(-ок)", Target = "gears", Amount = 40, PrizeList = new List<Quest.Prize> {
                        new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "autoturret", Amount = 1, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "supply.signal", Amount = 2, ExternalURL = "", Command = "",
                        }
                        , new Quest.Prize {
                            CustomItem = false, DisplayName = "", Skin = 0, Shortname = "", Amount = 1, ExternalURL = "https://i.imgur.com/9OJhuKj.png", Command = "emerald.give %STEAMID% Рубин 15",
                        }
                        ,
                    }
                }
            }
            ,
        }
        ;
        private Dictionary<ulong, List<PlayerQuest>> PlayerQuests = new Dictionary<ulong, List<PlayerQuest>>();
#region Data
        class PlayerData {
            public List<string> PlayerQuestsFinish = new List<string>();
            public Dictionary<string, double> PlayerQuestsCooldown = new Dictionary<string, double>();
        }
        class StoredData {
            public Dictionary<ulong, PlayerData> players = new Dictionary<ulong, PlayerData>();
        }
        void SaveData() {
            StatData.WriteObject(storedData);
        }
        void LoadData() {
            string resultName = this.Name + $"/playersCooldown";
            StatData = Interface.Oxide.DataFileSystem.GetFile(resultName);
            try {
                storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(resultName);
            }
            catch {
                storedData = new StoredData();
            }
        }
        StoredData storedData;
        private DynamicConfigFile StatData;
#endregion
#endregion
#region Метка на g карте
        private void CreateMarker(Vector3 position, float refreshRate, string name, string displayName, float radius = 0.10f, string colorMarker = "ff60df", string colorOutline = "00FFFFFF") {
            var marker = new GameObject().AddComponent<CustomMapMarker>();
            marker.name = name;
            marker.displayName = displayName;
            marker.radius = radius;
            marker.position = position;
            marker.refreshRate = refreshRate;
            ColorUtility.TryParseHtmlString($"#{colorMarker}", out marker.color1);
            ColorUtility.TryParseHtmlString($"#{colorOutline}", out marker.color2);
        }
        private void RemoveMarkers() {
            foreach (var marker in UnityEngine.Object.FindObjectsOfType<CustomMapMarker>()) {
                UnityEngine.Object.Destroy(marker);
            }
        }
        private const string genericPrefab = "assets/prefabs/tools/map/genericradiusmarker.prefab";
        private const string vendingPrefab = "assets/prefabs/deployable/vendingmachine/vending_mapmarker.prefab";
#region Scripts
        private class CustomMapMarker : MonoBehaviour {
            private VendingMachineMapMarker vending;
            private MapMarkerGenericRadius generic;
            public BaseEntity parent;
            private bool asChild;
            public float radius;
            public Color color1;
            public Color color2;
            public string displayName;
            public float refreshRate;
            public Vector3 position;
            public bool placedByPlayer;
            private void Start() {
                transform.position = position;
                asChild = parent != null;
                CreateMarkers();
            }
            private void CreateMarkers() {
                vending = GameManager.server.CreateEntity(vendingPrefab, position).GetComponent<VendingMachineMapMarker>();
                vending.markerShopName = displayName;
                vending.enableSaving = false;
                vending.Spawn();
                generic = GameManager.server.CreateEntity(genericPrefab).GetComponent<MapMarkerGenericRadius>();
                generic.color1 = color1;
                generic.color2 = color2;
                generic.radius = radius;
                generic.alpha = 1f;
                generic.enableSaving = false;
                generic.SetParent(vending);
                generic.Spawn();
                UpdateMarkers();
                if (refreshRate > 0f) {
                    if (asChild) {
                        InvokeRepeating(nameof(UpdatePosition), refreshRate, refreshRate);
                    }
                    else {
                        InvokeRepeating(nameof(UpdateMarkers), refreshRate, refreshRate);
                    }
                }
            }
            private void UpdatePosition() {
                if (asChild == true) {
                    if (parent.IsValid() == false) {
                        Destroy(this);
                        return;
                    }
                    else {
                        var pos = parent.transform.position;
                        transform.position = pos;
                        vending.transform.position = pos;
                    }
                }
                UpdateMarkers();
            }
            private void UpdateMarkers() {
                vending.SendNetworkUpdate();
                generic.SendUpdate();
            }
            private void DestroyMakers() {
                if (vending.IsValid()) {
                    vending.Kill();
                }
                if (generic.IsValid()) {
                    generic.Kill();
                }
            }
            private void OnDestroy() {
                DestroyMakers();
            }
        }
#endregion
#endregion
#region Initialization
        private void OnServerInitialized() {
            if (!ImageLibrary) {
                PrintError($"ERROR! Plugin ImageLibrary not found!");
                Interface.Oxide.UnloadPlugin(Title);
            }
            instance = this;
            LoadData("Quest", ref QuestList, false);
            LoadData("Players", ref PlayerQuests, true);
            LoadData();
            for (int i = 0; i < BasePlayer.activePlayerList.Count; i++) {
                OnPlayerConnected(BasePlayer.activePlayerList[i]);
            }
            for(int i = 0; i < QuestList.Count; i++) {
                for(int u = 0; u < QuestList[i].PrizeList.Count; u++) {
                    ImageLibrary.Call("AddImage", QuestList[i].PrizeList[u].ExternalURL, QuestList[i].PrizeList[u].ExternalURL);
                    if (QuestList[i].PrizeList[u].Skin != 0) ImageLibrary.Call("AddImage", $"http://rust.skyplugins.ru/getskin/{QuestList[i].PrizeList[u].Skin}/", QuestList[i].PrizeList[u].Shortname, QuestList[i].PrizeList[u].Skin);
                }
            }
            Unsubscribe("OnPlayerInput");
            if (!TryPlaceSign()) {
                PrintError($"ERROR! Plugin could not place sign!");
                return;
            }
        }
        void OnServerSave() {
            SaveData();
        }
#endregion
#region Functions
        private bool TryPlaceSign() {
            var monument = UnityEngine.Object.FindObjectsOfType<MonumentInfo>().FirstOrDefault(p => p.name.Contains("compound"));
            if (monument == null) {
                return false;
            }
            Vector3 resultVector = monument.transform.position + monument.transform.rotation * new Vector3(-5.4f, 0, -0.5f);
            List<BaseEntity> baseEntities = new List<BaseEntity>();
            Vis.Entities<BaseEntity>(resultVector, 3f, baseEntities);
            if (baseEntities.Count > 0) {
                foreach (var fdsf in baseEntities) {
                    if (fdsf.PrefabName.Contains("sign.post.town.roof")) fdsf.Kill();
                }
            }
            timer.Once(1, () => {
                Sign = GameManager.server.CreateEntity("assets/prefabs/deployable/signs/sign.post.town.roof.prefab", resultVector, monument.transform.rotation);
                Sign.SetFlag(BaseEntity.Flags.Locked, true);
                Sign.Spawn();
                if (config.MapMarkers) CreateMarker(Sign.transform.position, 5, "ЗАДАНИЯ", "ЗАДАНИЯ");
                RustMap?.Call("AddTemporaryMarker", "https://i.imgur.com/UtXBFFQ.png", "ЗАДАНИЯ", Sign.transform.position);
                ServerMgr.Instance.StartCoroutine(DownloadImage(config.ImageURL, Sign as Signage));
                Subscribe("OnPlayerInput");
            }
            );
            return true;
        }
#endregion
#region Hooks
        void OnNewSave(string filename) {
            if (config.WipeData) {
                PlayerQuests.Clear();
                storedData.players.Clear();
                PrintWarning("Обнаружен WIPE.Дата игроков сброшена");
            }
        }
        private void OnPlayerInput(BasePlayer player, InputState input) {
            if (input.WasJustPressed(BUTTON.USE) && Vector3.Distance(Sign.transform.position, player.transform.position) < 5) {
                player.SetFlag(BaseEntity.Flags.Reserved3, true);
                UI_DrawInterface(player);
            }
        }
        private void Unload() {
            for (int i = 0; i < BasePlayer.activePlayerList.Count; i++) {
                var player = BasePlayer.activePlayerList[i];
                if (UiOpen.Contains(player.userID)) {
                    UiOpen.Remove(player.userID);
                }
                CuiHelper.DestroyUi(player, Layer);
                BasePlayer p = BasePlayer.activePlayerList[i];
                p.SetFlag(BaseEntity.Flags.Reserved3, false);
            }
            if (Sign != null && !Sign.IsDestroyed) Sign.Kill();
            SaveData("Quest", QuestList, false);
            SaveData("Players", PlayerQuests, false);
            SaveData();
            if (config.MapMarkers) RemoveMarkers();
        }
        void OnPlayerConnected(BasePlayer player) {
            if (!PlayerQuests.ContainsKey(player.userID)) PlayerQuests.Add(player.userID, new List<PlayerQuest>());
            if (!storedData.players.ContainsKey(player.userID)) {
                storedData.players.Add(player.userID, new PlayerData());
            }
        }
#region Type Upgrade
        object OnStructureUpgrade(BaseCombatEntity entity, BasePlayer player, BuildingGrade.Enum grade) {
            List<PlayerQuest> playerQuests = null;
            if (PlayerQuests.TryGetValue(player.userID, out playerQuests)) {
                for(int i = 0; i < playerQuests.Count; i++) {
                    if (playerQuests[i].parentQuest.QuestType == QuestType.улучшить && playerQuests[i].Finished == false) {
                        if ((int)grade == Convert.ToInt16(playerQuests[i].parentQuest.Target)) {
                            playerQuests[i].AddCount();
                        }
                    }
                }
            }
            return null;
        }
#endregion
#region Type death
        private Dictionary<uint, Dictionary<ulong, int>> HeliAttackers = new Dictionary<uint, Dictionary<ulong, int>>();
        private void OnEntityDeath(BaseCombatEntity entity, HitInfo info) {
            try {
                if (entity == null || info == null) return;
                List<PlayerQuest> playerQuests = null;
                if (entity is NPCPlayer || entity is NPCMurderer) {
                    BasePlayer player = null;
                    if (info.InitiatorPlayer != null) player = info.InitiatorPlayer;
                    if (PlayerQuests.TryGetValue(player.userID, out playerQuests)) {
                        for (int i = 0; i < playerQuests.Count; i++) {
                            if (playerQuests[i].parentQuest.QuestType == QuestType.убить && playerQuests[i].Finished == false) {
                                if (entity.PrefabName.Contains(playerQuests[i].parentQuest.Target)) {
                                    playerQuests[i].AddCount();
                                }
                            }
                        }
                    }
                }
                else {
                    BasePlayer player = null;
                    if (info.InitiatorPlayer != null) player = info.InitiatorPlayer;
                    else if (entity.GetComponent<BaseHelicopter>() != null) player = BasePlayer.FindByID(GetLastAttacker(entity.net.ID));
                    if (entity.PrefabName.Contains("servergibs")) return;
                    if (PlayerQuests.TryGetValue(player.userID, out playerQuests)) {
                        for (int i = 0; i < playerQuests.Count; i++) {
                            if (playerQuests[i].parentQuest.QuestType == QuestType.убить && playerQuests[i].Finished == false) {
                                if (entity.PrefabName.Contains(playerQuests[i].parentQuest.Target)) {
                                    playerQuests[i].AddCount();
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex) {
            }
        }
        void OnEntityTakeDamage(BaseCombatEntity victim, HitInfo info) {
            if (victim.GetComponent<BaseHelicopter>() != null && info?.Initiator?.ToPlayer() != null) {
                var heli = victim.GetComponent<BaseHelicopter>();
                var player = info.Initiator.ToPlayer();
                NextTick(() => {
                    if (heli == null) return;
                    if (!HeliAttackers.ContainsKey(heli.net.ID)) HeliAttackers.Add(heli.net.ID, new Dictionary<ulong, int>());
                    if (!HeliAttackers[heli.net.ID].ContainsKey(player.userID)) HeliAttackers[heli.net.ID].Add(player.userID, 0);
                    HeliAttackers[heli.net.ID][player.userID]++;
                }
                );
            }
        }
        private ulong GetLastAttacker(uint id) {
            int hits = 0;
            ulong majorityPlayer = 0U;
            if (HeliAttackers.ContainsKey(id)) {
                foreach (var score in HeliAttackers[id]) {
                    if (score.Value > hits) majorityPlayer = score.Key;
                }
            }
            return majorityPlayer;
        }
#endregion
#region Type loot
        private void OnLootEntity(BasePlayer player, BaseEntity entity) {
            if (entity.OwnerID == 1337228 || entity.OwnerID >= 7656000000 || entity.GetComponent<LootContainer>() == null) return;
            List<PlayerQuest> playerQuests = null;
            if (PlayerQuests.TryGetValue(player.userID, out playerQuests)) {
                for (int i = 0; i < playerQuests.Count; i++) {
                    if (playerQuests[i].parentQuest.QuestType == QuestType.найти && playerQuests[i].Finished == false) {
                        for (int u = 0; u < entity.GetComponent<LootContainer>().inventory.itemList.Count();
                        u++) {
                            if (entity.GetComponent<LootContainer>().inventory.itemList[u].info.shortname.Contains(playerQuests[i].parentQuest.Target)) playerQuests[i].AddCount(entity.GetComponent<LootContainer>().inventory.itemList[u].amount);
                        }
                    }
                }
            }
            entity.OwnerID = 1337228;
        }
#endregion
#region Type Gather
        private void OnDispenserGather(ResourceDispenser dispenser, BaseEntity entity, Item item) {
            NextTick(() => {
                BasePlayer player;
                if (entity is BasePlayer) {
                    player = entity as BasePlayer;
                    List<PlayerQuest> playerQuests = null;
                    if (PlayerQuests.TryGetValue(player.userID, out playerQuests)) {
                        for (int i = 0; i < playerQuests.Count; i++) {
                            if (playerQuests[i].parentQuest.QuestType == QuestType.добыть && playerQuests[i].Finished == false) {
                                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 = null;
            if (PlayerQuests.TryGetValue(player.userID, out playerQuests)) {
                for (int i = 0; i < playerQuests.Count; i++) {
                    if (playerQuests[i].parentQuest.QuestType == QuestType.добыть && playerQuests[i].Finished == false) {
                        if (item.info.shortname.Contains(playerQuests[i].parentQuest.Target)) {
                            playerQuests[i].AddCount(item.amount);
                        }
                    }
                }
            }
        }
#endregion
#region Type craft
        void OnItemCraftFinished(ItemCraftTask task, Item item) {
            var player = task.owner;
            List<PlayerQuest> playerQuests = null;
            if (player != null && PlayerQuests.TryGetValue(player.userID, out playerQuests)) {
                for (int i = 0; i < playerQuests.Count; i++) {
                    if (playerQuests[i].parentQuest.QuestType == QuestType.скрафтить && playerQuests[i].Finished == false) {
                        if (task.blueprint.targetItem.shortname.Contains(playerQuests[i].parentQuest.Target)) {
                            playerQuests[i].AddCount(item.amount);
                        }
                    }
                }
            }
        }
#endregion
#endregion
#region Commands
        [ChatCommand("quest")]
        private void CmdChatQuest(BasePlayer player, string command, string[] args) {
            List<PlayerQuest> playerQuests = null;
            if (PlayerQuests.TryGetValue(player.userID, out playerQuests)) {
                if (args.Length > 0) {
                    switch (args[0].ToLower()) {
                        case "list" : {
                            if (playerQuests.Count == 0) {
                                SendChat(lang.GetMessage("QUEST_ACTIVE", this, player.UserIDString), lang.GetMessage("QUEST_ACTIVE_comp", this, player.UserIDString), player);
                                return;
                            }
                            else {
                                string message = "";
                                for(int i = 0; i < playerQuests.Count; i++) {
                                    message += $"\n{i + 1}.{playerQuests[i].parentQuest.DisplayName}\n\n" + $"{playerQuests[i].parentQuest.Description}\n";
                                    if (playerQuests[i].Finished) {
                                        message += lang.GetMessage("QUEST_ACTIVE_PROGRESS", this, player.UserIDString);
                                    }
                                    else {
                                        message += String.Format(lang.GetMessage("QUEST_ACTIVE_PROGRESS_GO", this, player.UserIDString), playerQuests[i].parentQuest.QuestType.ToString(), playerQuests[i].LeftAmount(), playerQuests[i].parentQuest.NiceTarget);
                                    }
                                }
                                SendChat(lang.GetMessage("QUEST_ACTIVE", this, player.UserIDString), message, player);
                                break;
                            }
                        }
                    }
                }
            }
        }
        [ConsoleCommand("UI_Handler")]
        private void CmdConsoleHandler(ConsoleSystem.Arg args) {
            BasePlayer player = args.Player();
            List<PlayerQuest> playerQuests = null;
            if (player != null && args.HasArgs(1) && PlayerQuests.TryGetValue(player.userID, out playerQuests)) {
                switch (args.Args[0]) {
                    case "get" : {
                        int questIndex;
                        if (args.HasArgs(2) && int.TryParse(args.Args[1], out questIndex)) {
                            var currentQuest = QuestList.ElementAtOrDefault(questIndex);
                            if (currentQuest != null) {
                                if (playerQuests.Count >= config.MaxQuestAmount) {
                                    SendChat(lang.GetMessage("QUEST", this, player.UserIDString), lang.GetMessage("QUEST_ACTIVE_LIMIT", this, player.UserIDString), player);
                                    return;
                                }
                                if (playerQuests.Any(p => p.parentQuest.DisplayName == currentQuest.DisplayName)) {
                                    SendChat(lang.GetMessage("QUEST", this, player.UserIDString), lang.GetMessage("QUEST_took_tasks", this, player.UserIDString), player);
                                    return;
                                }
                                if (!config.QuestGo && storedData.players[player.userID].PlayerQuestsFinish.Contains(currentQuest.DisplayName)) {
                                    SendChat(lang.GetMessage("QUEST", this, player.UserIDString), lang.GetMessage("QUEST_completed_tasks", this, player.UserIDString), player);
                                    return;
                                }
                                playerQuests.Add(new PlayerQuest() {
                                    UserID = player.userID, parentQuest = currentQuest
                                }
                                );
                                if(currentQuest.Cooldown != 0) {
                                    if (!storedData.players[player.userID].PlayerQuestsCooldown.ContainsKey(currentQuest.DisplayName)) {
                                        storedData.players[player.userID].PlayerQuestsCooldown.Add(currentQuest.DisplayName, 0);
                                    }
                                }
                                SendChat(lang.GetMessage("QUEST", this, player.UserIDString), String.Format(lang.GetMessage("QUEST_completed_took", this, player.UserIDString), currentQuest.DisplayName), player);
                                UI_DrawInterface(player, 0, questIndex.ToString());
                            }
                        }
                        break;
                    }
                    case "page" : {
                        int pageIndex;
                        if (int.TryParse(args.Args[1], out pageIndex)) {
                            UI_DrawInterface(player, pageIndex);
                        }
                        break;
                    }
                    case "finish" : {
                        int questIndex;
                        if (args.HasArgs(2) && int.TryParse(args.Args[1], out questIndex)) {
                            var globalQuest = QuestList.ElementAtOrDefault(questIndex);
                            if (globalQuest != null) {
                                var currentQuest = playerQuests.FirstOrDefault(p => p.parentQuest.DisplayName == globalQuest.DisplayName);
                                if (currentQuest == null) return;
                                if (currentQuest.Finished) {
                                    SendChat(lang.GetMessage("QUEST", this, player.UserIDString), lang.GetMessage("QUEST_tasks_completed", this, player.UserIDString), player);
                                    if (24 - player.inventory.containerMain.itemList.Count < currentQuest.parentQuest.PrizeList.Count) {
                                        SendChat(lang.GetMessage("QUEST", this, player.UserIDString), lang.GetMessage("QUEST_no_place", this, player.UserIDString), player);
                                        return;
                                    }
                                    else {
                                        currentQuest.Finished = false;
                                        for(int i = 0; i < currentQuest.parentQuest.PrizeList.Count; i++) {
                                            var check = currentQuest.parentQuest.PrizeList[i];
                                            if (check.Shortname != "") {
                                                if (check.CustomItem) {
                                                    Item newItem = ItemManager.CreateByPartialName(check.Shortname, check.Amount, check.Skin);
                                                    newItem.name = check.DisplayName;
                                                    newItem.MoveToContainer(player.inventory.containerMain);
                                                }
                                                else {
                                                    Item newItem = ItemManager.CreateByPartialName(check.Shortname, check.Amount);
                                                    if (check.Skin != 0) newItem.skin = check.Skin;
                                                    newItem.MoveToContainer(player.inventory.containerMain);
                                                }
                                            }
                                            if (check.Command != "") {
                                                Server.Command(check.Command.Replace("%STEAMID%", player.UserIDString));
                                            }
                                        }
                                    }
                                    if (!config.QuestGo && globalQuest.Cooldown == 0) {
                                        storedData.players[player.userID].PlayerQuestsFinish.Add(globalQuest.DisplayName);
                                    }
                                    else {
                                        storedData.players[player.userID].PlayerQuestsCooldown[globalQuest.DisplayName] = GetTimeStamp() + globalQuest.Cooldown;
                                    }
                                    playerQuests.Remove(currentQuest);
                                }
                                else {
                                    SendChat(lang.GetMessage("QUEST", this, player.UserIDString), lang.GetMessage("QUEST_did_not_cope", this, player.UserIDString), player);
                                    playerQuests.Remove(currentQuest);
                                }
                                UI_DrawInterface(player, 0, questIndex.ToString());
                            }
                            else {
                                SendChat(lang.GetMessage("QUEST", this, player.UserIDString), $"Вы <color=#4286f4>не брали</color> этого задания!", player);
                            }
                        }
                        break;
                    }
                }
            }
        }
        public List<ulong> UiOpen = new List<ulong>();
        [ConsoleCommand("Close_UI")]
        void CloseUiPlayer(ConsoleSystem.Arg arg) {
            arg.Player().SetFlag(BaseEntity.Flags.Reserved3, false);
            CuiHelper.DestroyUi(arg.Player(), Layer);
            if (UiOpen.Contains(arg.Player().userID)) {
                UiOpen.Remove(arg.Player().userID);
            }
        }
#endregion
        private IEnumerator StartUpdate(BasePlayer player) {
            while (player.HasFlag(BaseEntity.Flags.Reserved3)) {
                for (int i = 0; i < QuestList.Count();
                i++) {
                    var check = QuestList[i];
                    string questLayer = Layer + $".{i}";
                    if (storedData.players[player.userID].PlayerQuestsCooldown.ContainsKey(check.DisplayName)) {
                        if (storedData.players[player.userID]?.PlayerQuestsCooldown[check.DisplayName] >= GetTimeStamp()) {
                            CuiElementContainer container = new CuiElementContainer();
                            CuiHelper.DestroyUi(player, questLayer + ".Btn");
                            string text = TimeHelper.FormatTime(TimeSpan.FromSeconds(storedData.players[player.userID].PlayerQuestsCooldown[check.DisplayName] - GetTimeStamp()));
                            container.Add(new CuiButton {
                                RectTransform = {
                                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"
                                }
                                , Button = {
                                    Color = HexToRustFormat("#ba660b"), Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat", Command = "1"
                                }
                                , Text = {
                                    Text = text, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf", FontSize = 13, Color = HexToRustFormat("#d9e1c6")
                                }
                            }
                            , questLayer + ".BtnHolder", questLayer + ".Btn");
                            CuiHelper.AddUi(player, container);
                        }
                        else if(storedData.players[player.userID].PlayerQuestsCooldown[check.DisplayName] != 0) {
                            storedData.players[player.userID].PlayerQuestsCooldown.Remove(check.DisplayName);
                            UI_DrawInterface(player, 0, i.ToString());
                        }
                    }
                }
                yield return new WaitForSeconds(1);
            }
        }
#region Interface
        private const string Layer = "UI_Layer";
        private void UI_DrawInterface(BasePlayer player, int page = 0, string questUpdate = "") {
            List<PlayerQuest> playerQuests;
            if (!PlayerQuests.TryGetValue(player.userID, out playerQuests)) return;
            if (!UiOpen.Contains(player.userID)) {
                UiOpen.Add(player.userID);
            }
            CuiElementContainer container = new CuiElementContainer();
            if (questUpdate == "") {
                CuiHelper.DestroyUi(player, Layer);
                container.Add(new CuiPanel {
                    CursorEnabled = true, RectTransform = {
                        AnchorMin = "0.09687495 0.093518295", AnchorMax = "0.903125 0.9064815", OffsetMax = "0 0"
                    }
                    , Image = {
                        Color = "0 0 0 0"
                    }
                }
                , "Overlay", Layer);
                container.Add(new CuiButton {
                    RectTransform = {
                        AnchorMin = "-1 -1", AnchorMax = "2 2"
// ... [Code preview truncated due to length. Full source in attached file] ...

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