using System; using System.Collections.Generic; using System.Linq; using EFT; using EFT.Counters; using EFT.Interactive; using EFT.InventoryLogic; using EFT.Quests; using EFT.UI; using stupid.solutions.Data; using stupid.solutions.Features; using stupid.solutions.Features.ESP; using stupid.solutions.stupid.solutions.Data; using stupid.solutions.Utils; using UnityEngine; namespace stupid.solutions; public class QuestESP : MonoBehaviour { public struct QuestItemsSearched { public string ID { get; set; } } private List poiList = new List(); private List startedQuests = new List(); private bool shouldRefreshData = true; public static List QuestItemIds = new List(); private List placeItemTriggers = new List(); private List experienceTrigger = new List(); private bool gettriggers = true; private bool getquestitems = true; private float _nextQuestCacheTime; private static readonly float _cacheQuestInterval = 5f; public Color Color { get; set; } = Color.magenta; private void Update() { if (Settings.QuestESP && Time.time >= _nextQuestCacheTime) { if (Main.GameWorld != null && Main.LocalPlayer != null && Main.MainCamera != null) { try { poiList.Clear(); RefreshData(poiList); shouldRefreshData = false; } catch (Exception ex) { ConsoleScreen.Log("Error refreshing data: " + ex.Message); } } _nextQuestCacheTime = Time.time + _cacheQuestInterval; } if (gettriggers && Main.GameWorld != null && Main.LocalPlayer != null && Main.MainCamera != null) { GetTriggers(); } if (Main.GameWorld == null) { gettriggers = true; getquestitems = true; poiList.Clear(); QuestItemIds.Clear(); placeItemTriggers.Clear(); experienceTrigger.Clear(); } } public void GetTriggers() { if (placeItemTriggers == null) { placeItemTriggers = new List(); } if (experienceTrigger == null) { experienceTrigger = new List(); } gettriggers = false; placeItemTriggers.Clear(); experienceTrigger.Clear(); placeItemTriggers = UnityEngine.Object.FindObjectsOfType().ToList(); experienceTrigger = UnityEngine.Object.FindObjectsOfType().ToList(); ConsoleScreen.Log($"Got Triggers + {experienceTrigger.Count + placeItemTriggers.Count}"); } public void RefreshData(List data) { GameWorld gameWorld = Main.GameWorld; if (gameWorld == null) { return; } Player localPlayer = Main.LocalPlayer; if (localPlayer == null || Main.MainCamera == null) { return; } Profile profile = localPlayer.Profile; if (profile == null) { return; } try { List<_F286> questsData = profile.QuestsData; startedQuests.Clear(); foreach (_F286 item in questsData) { if (item.Template != null && item.Template.Conditions != null && profile.Stats != null && profile.Stats.Eft != null && profile.Stats.Eft.OverallCounters != null && item.Status == EQuestStatus.Started) { startedQuests.Add(item); } } if (startedQuests.Any()) { RefreshVisitPlaceLocations(startedQuests, profile, data); RefreshFindItemLocations(startedQuests, gameWorld, data); RefreshPlaceOrRepairItemLocations(startedQuests, profile, data); if (getquestitems) { RefreshNonStaticQuestItems(startedQuests, gameWorld, data); getquestitems = false; } } } catch (Exception) { } } private void RefreshVisitPlaceLocations(List startedQuests, Profile profile, List records) { try { List source = this.experienceTrigger.ToList(); foreach (dynamic startedQuest in startedQuests) { dynamic val = startedQuest.Template?.Conditions[EQuestStatus.AvailableForFinish]; if (val == null) { continue; } foreach (dynamic item in val) { try { if ((startedQuest.CompletedConditions.Contains(item.id)) || !(item is ConditionCounterCreator conditionCounterCreator)) { continue; } foreach (Condition condition in conditionCounterCreator.Conditions) { if (condition is ConditionVisitPlace conditionVisitPlace) { string expectedTriggerId = conditionVisitPlace.target; ExperienceTrigger experienceTrigger = source.FirstOrDefault((ExperienceTrigger t) => t.Id == expectedTriggerId); if (!(experienceTrigger == null) && profile.Stats.Eft.OverallCounters.GetInt(CounterTag.TriggerVisited, experienceTrigger.Id) <= 0) { Vector3 position = experienceTrigger.transform.position; AddQuestRecord(records, conditionCounterCreator, startedQuest, position, Color.cyan); break; } } } } catch (Exception ex) { ConsoleScreen.Log($"Error processing condition {(object)item?.id}: {ex.Message}"); } } } } catch (Exception) { } } private bool IsQuestConditionAvailableForFinish(dynamic quest) { dynamic val = quest.Template?.Conditions[EQuestStatus.AvailableForFinish]; return val != null && !quest.CompletedConditions.Contains(val.id); } private void RefreshFindItemLocations(List startedQuests, GameWorld world, List records) { try { _E3D7 lootItems = world.LootItems; for (int i = 0; i < lootItems.Count; i++) { try { LootItem byIndex = lootItems.GetByIndex(i); if (!GameUtils.IsLootItemValid(byIndex)) { continue; } bool flag = false; foreach (dynamic startedQuest in startedQuests) { dynamic val = startedQuest.Template?.Conditions[EQuestStatus.AvailableForFinish]; if (val == null) { continue; } foreach (object item in val) { if (!(item is ConditionFindItem conditionFindItem)) { continue; } string text = conditionFindItem.target.FirstOrDefault()?.ToString(); bool flag2 = text == null || !text.Contains(byIndex.Item.TemplateId.ToString()); if (!flag2 && !((flag2 | startedQuest.CompletedConditions.Contains(conditionFindItem.id)) ? true : false)) { if (!byIndex.Item.QuestItem && !flag) { QuestItemIds.Add(byIndex.Item.LocalizedName()); flag = true; } else { Vector3 position = byIndex.transform.position; AddQuestRecord(records, conditionFindItem, startedQuest, position, Color.yellow); } } } } } catch (Exception) { } } } catch (Exception) { } } private void RefreshNonStaticQuestItems(List startedQuests, GameWorld world, List records) { try { foreach (GameLootContainer gameLootContainer in LootableContainerESP._gameLootContainers) { if (!GameUtils.IsLootableContainerValid(gameLootContainer.LootableContainer)) { continue; } foreach (Item allItem in gameLootContainer.LootableContainer.ItemOwner.RootItem.GetAllItems()) { foreach (dynamic startedQuest in startedQuests) { dynamic val = startedQuest.Template?.Conditions[EQuestStatus.AvailableForFinish]; if (val == null) { continue; } bool flag = false; foreach (object item in val) { if (item is ConditionFindItem conditionFindItem) { string text = conditionFindItem.target.FirstOrDefault()?.ToString(); bool flag2 = text == null || !text.Contains(allItem.TemplateId.ToString()); if (!flag2 && !((flag2 | startedQuest.CompletedConditions.Contains(conditionFindItem.id)) ? true : false) && !allItem.QuestItem && !flag) { QuestItemIds.Add(allItem.LocalizedName()); flag = true; } } } } } } if (Main.OnlineGamePlayers.Count > 0) { foreach (OnlineGamePlayer onlineGamePlayer in Main.OnlineGamePlayers) { IEnumerator enumerator6 = onlineGamePlayer.Player.ObservedPlayerController.EquipmentViewController.Equipment.GetAllItems().GetEnumerator(); while (enumerator6.MoveNext()) { if (enumerator6.Current != null) { foreach (Item allItem2 in enumerator6.Current.GetAllItems()) { foreach (dynamic startedQuest2 in startedQuests) { dynamic val2 = startedQuest2.Template?.Conditions[EQuestStatus.AvailableForFinish]; if (!((val2 == null) ? true : false)) { bool flag3 = false; foreach (object item2 in val2) { if (item2 is ConditionFindItem conditionFindItem2) { string text2 = conditionFindItem2.target.FirstOrDefault()?.ToString(); bool flag2 = text2 == null || !text2.Contains(allItem2.TemplateId.ToString()); if (!flag2 && !((flag2 | startedQuest2.CompletedConditions.Contains(conditionFindItem2.id)) ? true : false) && !allItem2.QuestItem && !flag3) { QuestItemIds.Add(allItem2.LocalizedName()); flag3 = true; } } } } } } } } } return; } foreach (GamePlayer gamePlayer in Main.GamePlayers) { IEnumerator enumerator8 = gamePlayer.Player.Profile.Inventory.Equipment.GetAllItems().GetEnumerator(); while (enumerator8.MoveNext()) { if (enumerator8.Current == null) { continue; } foreach (Item allItem3 in enumerator8.Current.GetAllItems()) { foreach (dynamic startedQuest3 in startedQuests) { dynamic val3 = startedQuest3.Template?.Conditions[EQuestStatus.AvailableForFinish]; if (val3 == null) { continue; } bool flag4 = false; foreach (object item3 in val3) { if (item3 is ConditionFindItem conditionFindItem3) { string text3 = conditionFindItem3.target.FirstOrDefault()?.ToString(); bool flag2 = text3 == null || !text3.Contains(allItem3.TemplateId.ToString()); if (!flag2 && !((flag2 | startedQuest3.CompletedConditions.Contains(conditionFindItem3.id)) ? true : false) && !allItem3.QuestItem && !flag4) { QuestItemIds.Add(allItem3.LocalizedName()); flag4 = true; } } } } } } } } catch (Exception) { } } private void RefreshPlaceOrRepairItemLocations(List startedQuests, Profile profile, List records) { try { Item[] source = profile.Inventory.GetPlayerItems()?.ToArray(); List source2 = placeItemTriggers; foreach (dynamic startedQuest in startedQuests) { try { dynamic val = startedQuest.Template?.Conditions[EQuestStatus.AvailableForFinish]; if (val == null) { continue; } foreach (object item in val) { ConditionZone zoneCondition = item as ConditionZone; if (zoneCondition == null) { continue; } if (startedQuest.CompletedConditions.Contains(zoneCondition.id)) { continue; } string zoneconditionstring = zoneCondition.target.FirstOrDefault()?.ToString(); if (zoneconditionstring != null && source.FirstOrDefault((Item x) => zoneconditionstring.Contains(x.TemplateId.ToString())) != null) { PlaceItemTrigger placeItemTrigger = source2.FirstOrDefault((PlaceItemTrigger t) => t.Id == zoneCondition.zoneId); if (!(placeItemTrigger == null)) { Vector3 position = placeItemTrigger.transform.position; AddQuestRecord(records, zoneCondition, startedQuest, position, Color); break; } } } } catch (Exception) { } } } catch (Exception) { } } private void AddQuestRecord(List records, dynamic condition, dynamic quest, Vector3 position, Color color) { PointOfInterest item = new PointOfInterest { Name = $" {(object)quest.Template.Name} ", Description = $" {(object)condition.FormattedDescription} ", Position = position, Color = color, Quest = quest }; records.Add(item); } public void OnGUI() { if (!(Main.GameWorld != null) || !Settings.QuestESP) { return; } foreach (var item in (from poi in poiList group poi by new { poi.Position, poi.Name }).ToDictionary(g => g.Key, g => g.ToList())) { List value = item.Value; Vector3 position = item.Key.Position; Vector3 vector = GameUtils.WorldPointToScreenPoint(position); float num = Vector3.Distance(Main.MainCamera.transform.position, position); bool num2 = vector.z > 0f && vector.x > 0f && vector.x < (float)Screen.width && vector.y > 0f && vector.y < (float)Screen.height; bool flag = Aimbot.CaulculateInFov2(position) <= Settings.SimpleStringsFOV; if (!num2) { continue; } if (Settings.DrawSimpleStrings) { string label = (flag ? $"{item.Key.Name} [{num:F0}m]" : "[Q]"); Render.DrawString(new Vector2(vector.x - 50f, vector.y), label, value[0].Color); if (!flag || !Settings.DrawDescription) { continue; } float num3 = 15f; foreach (PointOfInterest item2 in value) { Render.DrawString(new Vector2(vector.x - 50f, vector.y + num3), item2.Description, Color.white); num3 += 15f; } continue; } string label2 = $"{item.Key.Name} [{num:F0}m]"; Render.DrawString(new Vector2(vector.x - 50f, vector.y), label2, value[0].Color); if (!Settings.DrawDescription) { continue; } float num4 = 15f; foreach (PointOfInterest item3 in value) { Render.DrawString(new Vector2(vector.x - 50f, vector.y + num4), item3.Description, Color.white); num4 += 15f; } } } }