using System; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEngine; /// <summary> /// Utility class for reading Json files for path information based on IDs /// </summary> public static class JsonReader { private readonly static string JsonStreamPath = Application.streamingAssetsPath + "/Jsons/"; private const string WeaponJson = "Weapons.json"; private const string ApparelJson = "Apparel.json"; private const string ConsumablesJson = "Consumables.json"; private const string GeneralJson = "General.json"; private const string ShopStock = "ShopStock.json"; private const string RelicJson = "Relics.json"; /// <summary> /// Reads the path file given and stores it in a wrapper to be returned as a list /// </summary> /// <param name="aspectPath">The path of the file to read</param> /// <returns>List of the aspect reference points</returns> private static List<AspectReference> ReadAspectJson(string aspectPath) { // Path construction to the correct File string jsonPath = JsonStreamPath + aspectPath; // Reads the Json file and creates the wrapper and outputs the collection of references string jsonStr = File.ReadAllText(jsonPath); AspectReferenceCollection list = JsonUtility.FromJson<AspectReferenceCollection>(jsonStr); return list.references; } /// <summary> /// Expanded form of ReadAspectJson that includes much more information meant for stores /// </summary> /// <returns></returns> private static List<AspectReferenceExpanded> ReadAspectJsonEXP() { string jsonPath = JsonStreamPath + ShopStock; string jsonStr = File.ReadAllText(jsonPath); AspectReferenceCollectionExpanded list = JsonUtility.FromJson<AspectReferenceCollectionExpanded>(jsonStr); return list.referencesExpanded; } /// <summary> /// Retrieves the items that are desired through the Json Reader and sends them in a package wrapper /// </summary> /// <typeparam name="T">The type of Scriptable Object to retrieve</typeparam> public static class AspectCollector<T> where T : ScriptableObject { /// <summary> /// Retrieval for the list of scriptable objects from the paths and IDs referenced /// </summary> /// <param name="path">The json file to be read from</param> /// <param name="ids">The list of ids to be taken from the file</param> /// <returns>List of the retrieved objects</returns> public static List<T> GatherAspects(string path, params int[] ids) { // If the function was called with no IDs, the function simply returns an empty list if (ids.Length is 0 || string.IsNullOrEmpty(path)) return new List<T>(); // Gathers the collection of References within the Json file based on the Json // ID passed to ReadJsonFIle. List<T> output = new List<T>(); List<AspectReference> refs = ReadAspectJson(path); // Counter variable to make parsing the Json list slightly faster int counter = 0; foreach (AspectReference val in refs) { // Checks if the value from the collection is one of the IDs // needed and if so adds it to the output if (ids.Contains(val.id)) { T contain = Resources.Load<T>(val.path); output.Add(contain); counter++; } // If the counter reaches the length of the IDs than the loop is broken // since all of the IDs neccessary were found if (counter == ids.Length) break; } return output; } /// <summary> /// Separate gathering system for shop stock by also including a value present in the Json File /// </summary> /// <param name="path">The json file desired</param> /// <param name="id">The ID of the stock desired</param> /// <returns>Dictionary of products with the amount based on the int Value as well as the owner and shop names</returns> public static (Dictionary<T, int>, string[]) GatherProductAspects(int id) { Dictionary<T, int> productsGathered = new Dictionary<T, int>(); string[] shopStringAspects = new string[2]; List<AspectReferenceExpanded> productRefs = ReadAspectJsonEXP(); foreach (AspectReferenceExpanded val in productRefs) { if (id == val.stockId) { try { List<WeaponSO> weaponsGathered = AspectCollector<WeaponSO>.GatherAspects(WeaponJson, val.weaponIds); weaponsGathered.Sort(comparison: (x, y) => x.ID.CompareTo(y.ID)); List<ApparelSO> apparelsGathered = AspectCollector<ApparelSO>.GatherAspects(ApparelJson, val.apparelIds); apparelsGathered.Sort(comparison: (x, y) => x.ID.CompareTo(y.ID)); List<ConsumableSO> consumablesGathered = AspectCollector<ConsumableSO>.GatherAspects(ConsumablesJson, val.consumableIds); consumablesGathered.Sort(comparison: (x, y) => x.ID.CompareTo(y.ID)); List<ItemSO> generalsGathered = AspectCollector<ItemSO>.GatherAspects(GeneralJson, val.generalIds); generalsGathered.Sort(comparison: (x, y) => x.ID.CompareTo(y.ID)); List<RelicSO> relicsGathered = AspectCollector<RelicSO>.GatherAspects(RelicJson, val.relicIds); int counter = 0; while (true) { // If each of the gathered stock counts are less than or equal to the current counter // this means that all of the stock available has been gathered if (counter >= weaponsGathered.Count && counter >= apparelsGathered.Count && counter >= consumablesGathered.Count && counter >= generalsGathered.Count) break; // Add to the Dictionary all of the gathered stock if (counter < weaponsGathered.Count) { T container = weaponsGathered[counter] as T; productsGathered.Add(container, val.weaponAmounts[counter]); } if (counter < apparelsGathered.Count) { T container = apparelsGathered[counter] as T; productsGathered.Add(container, val.apparelAmounts[counter]); } if (counter < consumablesGathered.Count) { T container = consumablesGathered[counter] as T; productsGathered.Add(container, val.consumableAmounts[counter]); } if (counter < generalsGathered.Count) { T container = generalsGathered[counter] as T; productsGathered.Add(container, val.generalAmounts[counter]); } if (counter < relicsGathered.Count) { T container = relicsGathered[counter] as T; productsGathered.Add(container, val.relicAmounts[counter]); } ++counter; } shopStringAspects[0] = val.ownerName; shopStringAspects[1] = val.shopName; } catch (IndexOutOfRangeException) { Debug.LogError("There was an index malfunction, please check the Aspect Json Files to make sure the amounts and ids match up!"); } break; } } return (productsGathered, shopStringAspects); } } }