예제 #1
0
        public IEnumerator RegisterAssetLoadLate(string bundlePath, string bundleName, LoadOrderType loadOrder)
        {
            //In order to get this bundle to load later, we want to replace the file path for the already loaded FVRObject
            string bundleID = bundlePath.Replace(bundleName, "") + " : " + bundleName.Replace("late_", "");

            OtherLoader.ManagedBundles[bundleID] = bundlePath;
            LoaderStatus.TrackLoader(bundleID, loadOrder);

            AnvilCallbackBase anvilCallbackBase;

            if (AnvilManager.m_bundles.TryGetValue(bundleID, out anvilCallbackBase))
            {
                AnvilManager.m_bundles.m_lookup.Remove(bundleID);
                AnvilManager.m_bundles.m_loading.Remove(anvilCallbackBase);

                if (OtherLoader.LogLoading.Value)
                {
                    OtherLogger.Log("Registered asset bundle to load later (" + bundlePath + ")", OtherLogger.LogType.General);
                    OtherLogger.Log("This bundle will replace the data bundle (" + bundleID + ")", OtherLogger.LogType.Loading);
                }
                else
                {
                    OtherLogger.Log("Registered asset bundle to load later (" + bundleName + ")", OtherLogger.LogType.General);
                    OtherLogger.Log("This bundle will replace the data bundle (" + LoaderUtils.GetBundleNameFromUniqueID(bundleID) + ")", OtherLogger.LogType.Loading);
                }
            }
            else
            {
                OtherLogger.LogError("Tried to register bundle to load later, but pre-bundle had not yet been loaded! (" + bundleID + ")");
            }

            yield return(null);
        }
예제 #2
0
        private void LoadFVRObjects(string bundleID, UnityEngine.Object[] allAssets)
        {
            foreach (FVRObject item in allAssets)
            {
                if (item == null)
                {
                    continue;
                }

                OtherLogger.Log("Loading FVRObject: " + item.ItemID, OtherLogger.LogType.Loading);

                if (IM.OD.ContainsKey(item.ItemID))
                {
                    OtherLogger.LogError("The ItemID of FVRObject is already used! Item will not be loaded! ItemID: " + item.ItemID);
                    continue;
                }
                item.m_anvilPrefab.Bundle = bundleID;

                if (item.CreditCost == 0)
                {
                    item.CalcCreditCost();                      //calculate credit cost if not set
                }
                IM.OD.Add(item.ItemID, item);
                ManagerSingleton <IM> .Instance.odicTagCategory.AddOrCreate(item.Category).Add(item);

                ManagerSingleton <IM> .Instance.odicTagFirearmEra.AddOrCreate(item.TagEra).Add(item);

                ManagerSingleton <IM> .Instance.odicTagFirearmSize.AddOrCreate(item.TagFirearmSize).Add(item);

                ManagerSingleton <IM> .Instance.odicTagFirearmAction.AddOrCreate(item.TagFirearmAction).Add(item);

                ManagerSingleton <IM> .Instance.odicTagAttachmentMount.AddOrCreate(item.TagAttachmentMount).Add(item);

                ManagerSingleton <IM> .Instance.odicTagAttachmentFeature.AddOrCreate(item.TagAttachmentFeature).Add(item);

                item.IsModContent = true;

                foreach (FVRObject.OTagFirearmFiringMode mode in item.TagFirearmFiringModes)
                {
                    ManagerSingleton <IM> .Instance.odicTagFirearmFiringMode.AddOrCreate(mode).Add(item);
                }
                foreach (FVRObject.OTagFirearmFeedOption feed in item.TagFirearmFeedOption)
                {
                    ManagerSingleton <IM> .Instance.odicTagFirearmFeedOption.AddOrCreate(feed).Add(item);
                }
                foreach (FVRObject.OTagFirearmMount mount in item.TagFirearmMounts)
                {
                    ManagerSingleton <IM> .Instance.odicTagFirearmMount.AddOrCreate(mount).Add(item);
                }
            }
        }
예제 #3
0
        public IEnumerator StartAssetLoad(FileSystemInfo handle, LoadOrderType loadOrder, bool allowUnload)
        {
            FileInfo file = handle.ConsumeFile();

            string bundleID = file.FullName.Replace(file.Name, "") + " : " + file.Name;

            return(LoadAssetsFromPathAsync(file.FullName, bundleID, "", new string[] { }, loadOrder, allowUnload).TryCatch(e =>
            {
                OtherLogger.LogError("Failed to load mod (" + bundleID + ")");
                OtherLogger.LogError(e.ToString());
                LoaderStatus.UpdateProgress(bundleID, 1);
                LoaderStatus.RemoveActiveLoader(bundleID, true);
            }));
        }
예제 #4
0
        private void LoadMechanicalAccuracyEntries(UnityEngine.Object[] allAssets)
        {
            foreach (FVRFireArmMechanicalAccuracyChart chart in allAssets)
            {
                foreach (FVRFireArmMechanicalAccuracyChart.MechanicalAccuracyEntry entry in chart.Entries)
                {
                    OtherLogger.Log("Loading new mechanical accuracy entry: " + entry.Class, OtherLogger.LogType.Loading);

                    if (!AM.SMechanicalAccuracyDic.ContainsKey(entry.Class))
                    {
                        AM.SMechanicalAccuracyDic.Add(entry.Class, entry);
                    }
                    else
                    {
                        OtherLogger.LogError("Duplicate mechanical accuracy class found, will not use one of them! Make sure you're using unique mechanical accuracy classes!");
                    }
                }
            }
        }
예제 #5
0
        public void LoadLegacyAssets(CoroutineStarter starter)
        {
            if (!Directory.Exists(OtherLoader.MainLegacyDirectory))
            {
                Directory.CreateDirectory(OtherLoader.MainLegacyDirectory);
            }

            OtherLogger.Log("Plugins folder found (" + Paths.PluginPath + ")", OtherLogger.LogType.General);

            List <string> legacyPaths = Directory.GetDirectories(Paths.PluginPath, "LegacyVirtualObjects", SearchOption.AllDirectories).ToList();

            legacyPaths.Add(OtherLoader.MainLegacyDirectory);

            foreach (string legacyPath in legacyPaths)
            {
                OtherLogger.Log("Legacy folder found (" + legacyPath + ")", OtherLogger.LogType.General);

                foreach (string bundlePath in Directory.GetFiles(legacyPath, "*", SearchOption.AllDirectories))
                {
                    //Only allow files without file extensions to be loaded (assumed to be an asset bundle)
                    if (Path.GetFileName(bundlePath) != Path.GetFileNameWithoutExtension(bundlePath))
                    {
                        continue;
                    }

                    string bundleID = bundlePath.Replace(Path.GetFileName(bundlePath), "") + " : " + Path.GetFileName(bundlePath);

                    IEnumerator routine = LoadAssetsFromPathAsync(bundlePath, bundleID, "", new string[] { }, LoadOrderType.LoadUnordered, true).TryCatch <Exception>(e =>
                    {
                        OtherLogger.LogError("Failed to load mod (" + bundleID + ")");
                        OtherLogger.LogError(e.ToString());
                        LoaderStatus.UpdateProgress(bundleID, 1);
                        LoaderStatus.RemoveActiveLoader(bundleID, true);
                    });

                    starter(routine);
                }
            }
        }
예제 #6
0
        public IEnumerator StartAssetLoadDirect(string folderPath, string bundleName, string guid, string[] dependancies, LoadOrderType loadOrder, bool allowUnload)
        {
            OtherLogger.Log("Direct Loading Bundle (" + bundleName + ")", OtherLogger.LogType.General);

            string      bundlePath = Path.Combine(folderPath, bundleName);
            string      lateName   = "late_" + bundleName;
            string      latePath   = Path.Combine(folderPath, lateName);
            string      bundleID   = bundlePath.Replace(bundleName, "") + " : " + bundleName;
            IEnumerator afterLoad  = null;

            if (File.Exists(latePath))
            {
                afterLoad = RegisterAssetLoadLate(latePath, lateName, loadOrder);
            }

            return(LoadAssetsFromPathAsync(bundlePath, bundleID, guid, dependancies, loadOrder, allowUnload, afterLoad).TryCatch(e =>
            {
                OtherLogger.LogError("Failed to load mod (" + bundleID + ")");
                OtherLogger.LogError(e.ToString());
                LoaderStatus.UpdateProgress(bundleID, 1);
                LoaderStatus.RemoveActiveLoader(bundleID, true);
            }));
        }
예제 #7
0
        private static bool DetailTextPatch(ItemSpawnerV2 __instance, string id, ref string __result)
        {
            FVRObject fvrObj;
            string    spawnerCat;
            string    spawnerSubcat;

            if (IM.Instance.SpawnerIDDic.ContainsKey(id))
            {
                OtherLogger.Log("Getting ID from spawnerID", OtherLogger.LogType.General);

                ItemSpawnerID spawnerID = IM.Instance.SpawnerIDDic[id];
                fvrObj = IM.OD[spawnerID.MainObject.ItemID];

                spawnerCat = spawnerID.Category.ToString();
                if (!Enum.IsDefined(typeof(ItemSpawnerID.EItemCategory), spawnerID.Category) && IM.CDefInfo.ContainsKey(spawnerID.Category))
                {
                    spawnerCat = IM.CDefInfo[spawnerID.Category].DisplayName;
                }

                spawnerSubcat = spawnerID.SubCategory.ToString();
                if (!Enum.IsDefined(typeof(ItemSpawnerID.ESubCategory), spawnerID.SubCategory) && IM.CDefSubInfo.ContainsKey(spawnerID.SubCategory))
                {
                    spawnerSubcat = IM.CDefSubInfo[spawnerID.SubCategory].DisplayName;
                }
            }

            else if (OtherLoader.SpawnerEntriesByID.ContainsKey(id))
            {
                OtherLogger.Log("Getting ID from otherloader", OtherLogger.LogType.General);

                spawnerCat    = "None";
                spawnerSubcat = "None";

                fvrObj = IM.OD[id];
            }

            else
            {
                OtherLogger.LogError($"The ItemID was not found to have spawner entry! ItemID: {id}");
                __result = "";
                return(false);
            }


            string text =
                "Spawner Category: " + spawnerCat + "\n" +
                "Spawner Subcategory: " + spawnerSubcat + "\n" +
                "Object Category: " + fvrObj.Category.ToString() + "\n" +
                "Set: " + fvrObj.TagSet.ToString() + "\n" +
                "Size: " + fvrObj.TagFirearmSize.ToString() + "\n" +
                "Era: " + fvrObj.TagEra.ToString() + "\n" +
                "Action: " + fvrObj.TagFirearmAction.ToString() + "\n" +
                "Round Power: " + fvrObj.TagFirearmRoundPower.ToString() + "\n" +
                "Country: " + fvrObj.TagFirearmCountryOfOrigin.ToString() + "\n" +
                "Introduction Year: " + fvrObj.TagFirearmFirstYear.ToString() + "\n" +
                "Magazine Type: " + fvrObj.MagazineType.ToString() + "\n" +
                "Round Type: " + fvrObj.RoundType.ToString() + "\n" +
                "Firing Modes: " + string.Join(",", fvrObj.TagFirearmFiringModes.Select(o => o.ToString()).ToArray()) + "\n" +
                "Feed Options: " + string.Join(",", fvrObj.TagFirearmFeedOption.Select(o => o.ToString()).ToArray()) + "\n" +
                "Mounts: " + string.Join(",", fvrObj.TagFirearmMounts.Select(o => o.ToString()).ToArray()) + "\n" +
                "Attachment Mount: " + fvrObj.TagAttachmentMount.ToString() + "\n" +
                "Attachment Feature: " + fvrObj.TagAttachmentFeature.ToString();

            __result = text;

            return(false);
        }
예제 #8
0
        private void LoadBulletData(UnityEngine.Object[] allAssets)
        {
            foreach (FVRFireArmRoundDisplayData data in allAssets)
            {
                if (data == null)
                {
                    continue;
                }

                OtherLogger.Log("Loading ammo type: " + data.Type, OtherLogger.LogType.Loading);

                if (!AM.STypeDic.ContainsKey(data.Type))
                {
                    OtherLogger.Log("This is a new ammo type! Adding it to dictionary", OtherLogger.LogType.Loading);
                    AM.STypeDic.Add(data.Type, new Dictionary <FireArmRoundClass, FVRFireArmRoundDisplayData.DisplayDataClass>());
                }
                else
                {
                    OtherLogger.Log("This is an existing ammo type, will add subclasses to this type", OtherLogger.LogType.Loading);
                }

                if (!AM.STypeList.Contains(data.Type))
                {
                    AM.STypeList.Add(data.Type);
                }

                if (!AM.SRoundDisplayDataDic.ContainsKey(data.Type))
                {
                    AM.SRoundDisplayDataDic.Add(data.Type, data);
                }

                //If this Display Data already exists, then we should add our classes to the existing display data class list
                else
                {
                    List <FVRFireArmRoundDisplayData.DisplayDataClass> classes = new List <FVRFireArmRoundDisplayData.DisplayDataClass>(AM.SRoundDisplayDataDic[data.Type].Classes);
                    classes.AddRange(data.Classes);
                    AM.SRoundDisplayDataDic[data.Type].Classes = classes.ToArray();
                }

                if (!AM.STypeClassLists.ContainsKey(data.Type))
                {
                    AM.STypeClassLists.Add(data.Type, new List <FireArmRoundClass>());
                }

                foreach (FVRFireArmRoundDisplayData.DisplayDataClass roundClass in data.Classes)
                {
                    OtherLogger.Log("Loading ammo class: " + roundClass.Class, OtherLogger.LogType.Loading);
                    if (!AM.STypeDic[data.Type].ContainsKey(roundClass.Class))
                    {
                        OtherLogger.Log("This is a new ammo class! Adding it to dictionary", OtherLogger.LogType.Loading);
                        AM.STypeDic[data.Type].Add(roundClass.Class, roundClass);
                    }
                    else
                    {
                        OtherLogger.LogError("Ammo class already exists for bullet type! Bullet will not be loaded! Type: " + data.Type + ", Class: " + roundClass.Class);
                        return;
                    }

                    if (!AM.STypeClassLists[data.Type].Contains(roundClass.Class))
                    {
                        AM.STypeClassLists[data.Type].Add(roundClass.Class);
                    }
                }
            }
        }
예제 #9
0
        private void LoadSpawnerIDs(UnityEngine.Object[] allAssets)
        {
            foreach (ItemSpawnerID id in allAssets)
            {
                OtherLogger.Log("Adding Itemspawner ID! Category: " + id.Category + ", SubCategory: " + id.SubCategory, OtherLogger.LogType.Loading);

                //Try to set the main object of this ID as a secondary if the main is null (so that it gets tagged properly)
                if (id.MainObject == null && id.Secondaries.Length > 0)
                {
                    id.MainObject = id.Secondaries.Select(o => o.MainObject).FirstOrDefault(o => o != null);
                    if (id.MainObject == null)
                    {
                        OtherLogger.Log("Could not select a secondary object for ItemSpawnerID, it will not appear in spawner: Display Name: " + id.DisplayName, OtherLogger.LogType.Loading);
                    }
                    else
                    {
                        id.ItemID = id.MainObject.ItemID;
                    }
                }


                if (id.MainObject != null)
                {
                    if (id.UnlockCost == 0)
                    {
                        id.UnlockCost = id.MainObject.CreditCost;
                    }

                    IM.RegisterItemIntoMetaTagSystem(id);
                    if (!id.IsDisplayedInMainEntry)
                    {
                        HideItemFromCategories(id);
                    }
                }


                if (IM.CD.ContainsKey(id.Category) && IM.SCD.ContainsKey(id.SubCategory))
                {
                    IM.CD[id.Category].Add(id);
                    IM.SCD[id.SubCategory].Add(id);

                    if (!ManagerSingleton <IM> .Instance.SpawnerIDDic.ContainsKey(id.ItemID))
                    {
                        ManagerSingleton <IM> .Instance.SpawnerIDDic[id.ItemID] = id;

                        //Now we will try to convert this SpawnerID into a spawner entry
                        ItemSpawnerEntry SpawnerEntry = ScriptableObject.CreateInstance <ItemSpawnerEntry>();

                        //If the category is defined, we can try to add it based on what page it was given
                        if (Enum.IsDefined(typeof(ItemSpawnerID.EItemCategory), id.Category))
                        {
                            //TODO this should be done without having to loop through potentially all spawner entries, I bet this could become expensive
                            bool added = false;
                            foreach (KeyValuePair <ItemSpawnerV2.PageMode, List <string> > pageItems in IM.Instance.PageItemLists)
                            {
                                if (pageItems.Value.Contains(id.ItemID))
                                {
                                    OtherLogger.Log("Adding SpawnerID to spawner entry tree", OtherLogger.LogType.Loading);
                                    SpawnerEntry.LegacyPopulateFromID(pageItems.Key, id, true);
                                    PopulateEntryPaths(SpawnerEntry, id);
                                    added = true;

                                    break;
                                }
                            }

                            if (added)
                            {
                                continue;
                            }

                            //If we make it to this point, we failed to add the entry to the tree structure, but should still populate the entries data
                            OtherLogger.Log("ItemSpawnerID could not be converted for new spawner because of metadata issues! ItemID: " + id.ItemID, OtherLogger.LogType.Loading);
                            SpawnerEntry.LegacyPopulateFromID(ItemSpawnerV2.PageMode.Firearms, id, true);
                        }

                        //Otherwise, all custom category items go under the firearms page
                        else
                        {
                            OtherLogger.Log("Adding SpawnerID to spawner entry tree under custom category", OtherLogger.LogType.Loading);
                            SpawnerEntry.LegacyPopulateFromID(ItemSpawnerV2.PageMode.Firearms, id, true);
                            PopulateEntryPaths(SpawnerEntry, id);
                        }
                    }
                }

                else
                {
                    OtherLogger.LogError("ItemSpawnerID could not be added, because either the main category or subcategory were not loaded! Item will not appear in the itemspawner! Item Display Name: " + id.DisplayName);
                }
            }
        }
예제 #10
0
        private IEnumerator LoadAssetsFromPathAsync(string path, string bundleID, string guid, string[] dependancies, LoadOrderType loadOrder, bool allowUnload, IEnumerator afterLoad = null)
        {
            //Start tracking this bundle and then wait a frame for everything else to be tracked
            LoaderStatus.TrackLoader(bundleID, loadOrder);
            yield return(null);

            //If there are many active loaders at once, we should wait our turn
            bool overTime = false;

            while (!LoaderStatus.CanOrderedModLoad(bundleID))
            {
                if (!overTime && Time.time - LoaderStatus.LastLoadEventTime > 30)
                {
                    OtherLogger.Log("Bundle has been waiting a long time to load! (" + bundleID + ")", OtherLogger.LogType.General);
                    LoaderStatus.PrintWaitingBundles(bundleID);
                    overTime = true;
                }

                yield return(null);
            }

            //Begin the loading process
            LoaderStatus.AddActiveLoader(bundleID);

            if (OtherLoader.LogLoading.Value)
            {
                OtherLogger.Log("Beginning async loading of asset bundle (" + bundleID + ")", OtherLogger.LogType.General);
            }


            //Load the bundle and apply it's contents
            float time = Time.time;

            LoaderStatus.UpdateProgress(bundleID, UnityEngine.Random.Range(.1f, .3f));

            AnvilCallback <AssetBundle> bundle = LoaderUtils.LoadAssetBundle(path);

            yield return(bundle);

            LoaderStatus.UpdateProgress(bundleID, 0.9f);

            yield return(ApplyLoadedAssetBundleAsync(bundle, bundleID).TryCatch(e =>
            {
                OtherLogger.LogError("Failed to load mod (" + bundleID + ")");
                OtherLogger.LogError(e.ToString());
                LoaderStatus.UpdateProgress(bundleID, 1);
                LoaderStatus.RemoveActiveLoader(bundleID, true);
            }));


            //Log that the bundle is loaded
            if (OtherLoader.LogLoading.Value)
            {
                OtherLogger.Log($"[{(Time.time - time).ToString("0.000")} s] Completed loading bundle ({bundleID})", OtherLogger.LogType.General);
            }
            else
            {
                OtherLogger.Log($"[{(Time.time - time).ToString("0.000")} s] Completed loading bundle ({LoaderUtils.GetBundleNameFromUniqueID(bundleID)})", OtherLogger.LogType.General);
            }



            if (allowUnload && OtherLoader.OptimizeMemory.Value)
            {
                OtherLogger.Log("Unloading asset bundle (Optimize Memory is true)", OtherLogger.LogType.Loading);
                bundle.Result.Unload(false);
            }
            else
            {
                AnvilManager.m_bundles.Add(bundleID, bundle);
            }

            OtherLoader.ManagedBundles.Add(bundleID, path);
            LoaderStatus.UpdateProgress(bundleID, 1);
            LoaderStatus.RemoveActiveLoader(bundleID, !(OtherLoader.OptimizeMemory.Value && allowUnload));

            if (afterLoad != null)
            {
                yield return(afterLoad);
            }
        }