/// <summary>
        /// Spawns items from the equipment group
        /// </summary>
        /// <param name="selectedGroup"></param>
        /// <param name="position"></param>
        /// <param name="rotation"></param>
        /// <param name="callback"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        public static IEnumerator InstantiateFromEquipmentGroup(EquipmentGroup selectedGroup, Vector3 position, Quaternion rotation, Action <GameObject> callback = null, float tolerance = 1.3f)
        {
            float currentHeight = 0;

            foreach (EquipmentGroup group in selectedGroup.GetSpawnedEquipmentGroups())
            {
                for (int i = 0; i < group.ItemsToSpawn; i++)
                {
                    FVRObject selectedFVR;
                    if (IM.OD.TryGetValue(group.GetObjects().GetRandom(), out selectedFVR))
                    {
                        //First, async get the game object to spawn
                        AnvilCallback <GameObject> objectCallback = selectedFVR.GetGameObjectAsync();
                        yield return(objectCallback);

                        GameObject gameObject = objectCallback.Result;

                        //Next calculate the height needed for this item
                        float heightNeeded = gameObject.GetMaxBounds().size.y / 2 * tolerance;
                        currentHeight += heightNeeded;

                        //Finally spawn the item and call the callback if it's not null
                        GameObject spawnedObject = UnityEngine.GameObject.Instantiate(gameObject, position + (Vector3.up * currentHeight), rotation);
                        if (callback != null)
                        {
                            callback.Invoke(spawnedObject);
                        }
                        yield return(null);
                    }
                }
            }
        }
Пример #2
0
        public static AnvilCallback <AssetBundle> LoadAssetBundle(string path)
        {
            AsyncOperation request = AssetBundle.LoadFromFileAsync(path);

            AnvilCallbackBase anvilCallbackBase = new AnvilCallback <AssetBundle>(request, null);

            return((AnvilCallback <AssetBundle>)anvilCallbackBase);
        }
Пример #3
0
        public static void IM_GenerateItemDBs(GM __instance)
        {
            Uri StreamingAssetsUri = new Uri(Application.streamingAssetsPath + "\\dummy");

            Logger.LogDebug(Application.streamingAssetsPath + "\\dummy");
            foreach (string file in Directory.GetFiles(Paths.GameRootPath + @"\VirtualObjects", "*", SearchOption.AllDirectories))
            {
                if (Path.GetFileName(file) != Path.GetFileNameWithoutExtension(file) || Path.GetFileName(file).Contains("VirtualObjects"))
                {
                    continue;
                }

                string relativeFile = StreamingAssetsUri.MakeRelativeUri(new Uri(file)).ToString();

                AnvilCallback <AssetBundle> bundle = AnvilManager.GetBundleAsync(relativeFile);
                bundle.AddCallback(delegate
                {
                    if (bundle.Result != null)
                    {
                        Logger.Log(LogLevel.Info, $"Injecting FVRObject(s) and ItemSpawnerID(s) from {Path.GetFileName(file)}");

                        foreach (FVRObject fvrObj in bundle.Result.LoadAllAssets <FVRObject>())
                        {
                            //allows the original bundle path to be ignored, a bit cursed
                            FieldInfo anvilPrefab = AccessTools.Field(typeof(FVRObject), "m_anvilPrefab");
                            AssetID original      = (AssetID)anvilPrefab.GetValue(fvrObj);
                            original.Bundle       = relativeFile;
                            anvilPrefab.SetValue(fvrObj, original);

                            IM.OD.Add(fvrObj.ItemID, fvrObj);

                            ManagerSingleton <IM> .Instance.odicTagCategory.AddOrCreate(fvrObj.Category).Add(fvrObj);
                            ManagerSingleton <IM> .Instance.odicTagFirearmEra.AddOrCreate(fvrObj.TagEra).Add(fvrObj);
                            ManagerSingleton <IM> .Instance.odicTagFirearmSize.AddOrCreate(fvrObj.TagFirearmSize).Add(fvrObj);
                            ManagerSingleton <IM> .Instance.odicTagFirearmAction.AddOrCreate(fvrObj.TagFirearmAction).Add(fvrObj);
                            ManagerSingleton <IM> .Instance.odicTagFirearmFiringMode.AddOrCreate(fvrObj.TagFirearmFiringModes.FirstOrDefault()).Add(fvrObj);
                            ManagerSingleton <IM> .Instance.odicTagFirearmFeedOption.AddOrCreate(fvrObj.TagFirearmFeedOption.FirstOrDefault()).Add(fvrObj);
                            ManagerSingleton <IM> .Instance.odicTagFirearmMount.AddOrCreate(fvrObj.TagFirearmMounts.FirstOrDefault()).Add(fvrObj);
                            ManagerSingleton <IM> .Instance.odicTagAttachmentMount.AddOrCreate(fvrObj.TagAttachmentMount).Add(fvrObj);
                            ManagerSingleton <IM> .Instance.odicTagAttachmentFeature.AddOrCreate(fvrObj.TagAttachmentFeature).Add(fvrObj);
                        }
                        foreach (ItemSpawnerID id in bundle.Result.LoadAllAssets <ItemSpawnerID>())
                        {
                            IM.CD[id.Category].Add(id);
                            IM.SCD[id.SubCategory].Add(id);
                        }
                    }
                    else
                    {
                        Logger.LogError("AssetBundle is somehow null, what did you do?");
                    }
                });
            }
        }
Пример #4
0
        private static bool LoadModdedBundlesPatch(string bundle, ref AnvilCallback <AssetBundle> __result)
        {
            if (ManagedBundles.ContainsKey(bundle))
            {
                //If this is a modded bundle, we should first check if the bundle is already loaded
                AnvilCallbackBase anvilCallbackBase;
                if (AnvilManager.m_bundles.TryGetValue(bundle, out anvilCallbackBase))
                {
                    OtherLogger.Log("Tried to load modded asset bundle, and it's already loaded : " + bundle, OtherLogger.LogType.Loading);
                    __result = anvilCallbackBase as AnvilCallback <AssetBundle>;
                    return(false);
                }

                //If the bundle is not already loaded, then load it
                else
                {
                    OtherLogger.Log("Tried to load modded asset bundle, and it's not yet loaded : " + bundle, OtherLogger.LogType.Loading);

                    AnvilCallback <AssetBundle> mainCallback = LoaderUtils.LoadAssetBundle(ManagedBundles[bundle]);
                    List <BundleInfo>           dependencies = LoaderStatus.GetBundleDependencies(bundle);

                    if (dependencies.Count > 0)
                    {
                        OtherLogger.Log("Dependencies:", OtherLogger.LogType.Loading);
                        dependencies.ForEach(o => OtherLogger.Log(ManagedBundles[o.BundleID], OtherLogger.LogType.Loading));

                        //Start with the last dependency, and loop through from second to last dep up to the first dep
                        //The first dep in the list is the dependency for all other dependencies, so it is the deepest
                        AnvilCallback <AssetBundle> dependency = LoaderUtils.LoadAssetBundle(ManagedBundles[dependencies.Last().BundleID]);
                        mainCallback.m_dependancy = dependency;
                        AnvilManager.m_bundles.Add(dependencies.Last().BundleID, dependency);

                        for (int i = dependencies.Count - 2; i >= 0; i--)
                        {
                            dependency.m_dependancy = LoaderUtils.LoadAssetBundle(ManagedBundles[dependencies[i].BundleID]);
                            dependency = dependency.m_dependancy;
                            AnvilManager.m_bundles.Add(dependencies[i].BundleID, dependency);
                        }
                    }

                    __result = mainCallback;
                    AnvilManager.m_bundles.Add(bundle, __result);
                    return(false);
                }
            }

            return(true);
        }
Пример #5
0
        private void UnloadAllModdedBundles()
        {
            foreach (string bundleID in ManagedBundles.Keys)
            {
                if (!AnvilManager.m_bundles.m_lookup.ContainsKey(bundleID))
                {
                    continue;
                }

                OtherLogger.Log("Unloading bundle: " + bundleID, OtherLogger.LogType.General);

                //Get the bundle container
                AnvilCallback <AssetBundle> bundleCallback = (AnvilCallback <AssetBundle>)AnvilManager.m_bundles.m_lookup[bundleID];

                //Remove Instances of this bundle from the anvil manager
                AnvilManager.m_bundles.m_loading.Remove(AnvilManager.m_bundles.m_lookup[bundleID]);
                AnvilManager.m_bundles.m_lookup.Remove(bundleID);

                //Unload the bundle
                bundleCallback.Result.Unload(false);
            }
        }
Пример #6
0
 public static void AddMonitoredAnvilCallback(AnvilCallback <AssetBundle> __result)
 {
     AsyncLoadMonitor.CallbackList.Add(__result);
     TNHTweakerLogger.Log("TNHTweaker -- Added AssetBundle anvil callback to monitored callbacks!", TNHTweakerLogger.LogType.File);
 }
Пример #7
0
        private IEnumerator ApplyLoadedAssetBundleAsync(AnvilCallback <AssetBundle> bundle, string bundleID)
        {
            //Load the mechanical accuracy entries
            AssetBundleRequest accuracyCharts = bundle.Result.LoadAllAssetsAsync <FVRFireArmMechanicalAccuracyChart>();

            yield return(accuracyCharts);

            LoadMechanicalAccuracyEntries(accuracyCharts.allAssets);

            //Load all the FVRObjects
            AssetBundleRequest fvrObjects = bundle.Result.LoadAllAssetsAsync <FVRObject>();

            yield return(fvrObjects);

            LoadFVRObjects(bundleID, fvrObjects.allAssets);

            //Now all the FVRObjects are loaded, we can load the bullet data
            AssetBundleRequest bulletData = bundle.Result.LoadAllAssetsAsync <FVRFireArmRoundDisplayData>();

            yield return(bulletData);

            LoadBulletData(bulletData.allAssets);

            //Before we load the spawnerIDs, we must add any new spawner category definitions
            AssetBundleRequest spawnerCats = bundle.Result.LoadAllAssetsAsync <ItemSpawnerCategoryDefinitions>();

            yield return(spawnerCats);

            LoadSpawnerCategories(spawnerCats.allAssets);

            //Load the legacy spawner IDs
            AssetBundleRequest spawnerIDs = bundle.Result.LoadAllAssetsAsync <ItemSpawnerID>();

            yield return(spawnerIDs);

            LoadSpawnerIDs(spawnerIDs.allAssets);

            //Load the spawner entries for the new spawner
            AssetBundleRequest spawnerEntries = bundle.Result.LoadAllAssetsAsync <ItemSpawnerEntry>();

            yield return(spawnerEntries);

            LoadSpawnerEntries(spawnerEntries.allAssets);

            //handle handling grab/release/slot sets
            AssetBundleRequest HandlingGrabSet = bundle.Result.LoadAllAssetsAsync <HandlingGrabSet>();

            yield return(HandlingGrabSet);

            LoadHandlingGrabSetEntries(HandlingGrabSet.allAssets);

            AssetBundleRequest HandlingReleaseSet = bundle.Result.LoadAllAssetsAsync <HandlingReleaseSet>();

            yield return(HandlingReleaseSet);

            LoadHandlingReleaseSetEntries(HandlingReleaseSet.allAssets);

            AssetBundleRequest HandlingSlotSet = bundle.Result.LoadAllAssetsAsync <HandlingReleaseIntoSlotSet>();

            yield return(HandlingSlotSet);

            LoadHandlingSlotSetEntries(HandlingSlotSet.allAssets);

            //audio bullet impact sets; handled similarly to the ones above
            AssetBundleRequest BulletImpactSet = bundle.Result.LoadAllAssetsAsync <AudioBulletImpactSet>();

            yield return(BulletImpactSet);

            LoadImpactSetEntries(BulletImpactSet.allAssets);

            AssetBundleRequest AudioImpactSet = bundle.Result.LoadAllAssetsAsync <AudioImpactSet>();

            yield return(AudioImpactSet);

            LoadAudioImpactSetEntries(AudioImpactSet.allAssets);

            AssetBundleRequest Quickbelts = bundle.Result.LoadAllAssetsAsync <GameObject>();

            yield return(Quickbelts);

            LoadQuickbeltEntries(Quickbelts.allAssets);
        }
Пример #8
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);
            }
        }
        public static IEnumerator SpawnFirearm(SavedGunSerializable savedGun, Vector3 position, Quaternion rotation)
        {
            List <GameObject>  toDealWith    = new List <GameObject>();
            List <GameObject>  toMoveToTrays = new List <GameObject>();
            FVRFireArm         myGun         = null;
            FVRFireArmMagazine myMagazine    = null;
            List <int>         validIndexes  = new List <int>();
            Dictionary <GameObject, SavedGunComponent> dicGO = new Dictionary <GameObject, SavedGunComponent>();
            Dictionary <int, GameObject> dicByIndex          = new Dictionary <int, GameObject>();
            List <GameObject>            gameObjects         = new List <GameObject>();
            SavedGun gun = savedGun.GetSavedGun();

            for (int i = 0; i < gun.Components.Count; i++)
            {
                AnvilCallback <GameObject> gameObjectCallback = IM.OD[gun.Components[i].ObjectID].GetGameObjectAsync();

                TNHTweakerLogger.Log($"Loading vault component: {gun.Components[i].ObjectID}", TNHTweakerLogger.LogType.General);

                yield return(gameObjectCallback);

                gameObjects.Add(gameObjectCallback.Result);
            }

            for (int j = 0; j < gun.Components.Count; j++)
            {
                GameObject gameObject = UnityEngine.Object.Instantiate(gameObjects[j]);

                dicGO.Add(gameObject, gun.Components[j]);
                dicByIndex.Add(gun.Components[j].Index, gameObject);
                if (gun.Components[j].isFirearm)
                {
                    myGun = gameObject.GetComponent <FVRFireArm>();
                    savedGun.ApplyFirearmProperties(myGun);

                    validIndexes.Add(j);
                    gameObject.transform.position = position;
                    gameObject.transform.rotation = Quaternion.identity;
                }
                else if (gun.Components[j].isMagazine)
                {
                    myMagazine = gameObject.GetComponent <FVRFireArmMagazine>();
                    validIndexes.Add(j);
                    if (myMagazine != null)
                    {
                        gameObject.transform.position = myGun.GetMagMountPos(myMagazine.IsBeltBox).position;
                        gameObject.transform.rotation = myGun.GetMagMountPos(myMagazine.IsBeltBox).rotation;
                        myMagazine.Load(myGun);
                        myMagazine.IsInfinite = false;
                    }
                }
                else if (gun.Components[j].isAttachment)
                {
                    toDealWith.Add(gameObject);
                }
                else
                {
                    toMoveToTrays.Add(gameObject);
                    if (gameObject.GetComponent <Speedloader>() != null && gun.LoadedRoundsInMag.Count > 0)
                    {
                        Speedloader component = gameObject.GetComponent <Speedloader>();
                        component.ReloadSpeedLoaderWithList(gun.LoadedRoundsInMag);
                    }
                    else if (gameObject.GetComponent <FVRFireArmClip>() != null && gun.LoadedRoundsInMag.Count > 0)
                    {
                        FVRFireArmClip component2 = gameObject.GetComponent <FVRFireArmClip>();
                        component2.ReloadClipWithList(gun.LoadedRoundsInMag);
                    }
                }
                gameObject.GetComponent <FVRPhysicalObject>().ConfigureFromFlagDic(gun.Components[j].Flags);
            }
            if (myGun.Magazine != null && gun.LoadedRoundsInMag.Count > 0)
            {
                myGun.Magazine.ReloadMagWithList(gun.LoadedRoundsInMag);
                myGun.Magazine.IsInfinite = false;
            }
            int BreakIterator = 200;

            while (toDealWith.Count > 0 && BreakIterator > 0)
            {
                BreakIterator--;
                for (int k = toDealWith.Count - 1; k >= 0; k--)
                {
                    SavedGunComponent savedGunComponent = dicGO[toDealWith[k]];
                    if (validIndexes.Contains(savedGunComponent.ObjectAttachedTo))
                    {
                        GameObject                gameObject2 = toDealWith[k];
                        FVRFireArmAttachment      component3  = gameObject2.GetComponent <FVRFireArmAttachment>();
                        FVRFireArmAttachmentMount mount       = GetMount(dicByIndex[savedGunComponent.ObjectAttachedTo], savedGunComponent.MountAttachedTo);
                        gameObject2.transform.rotation = Quaternion.LookRotation(savedGunComponent.OrientationForward, savedGunComponent.OrientationUp);
                        gameObject2.transform.position = GetPositionRelativeToGun(savedGunComponent, myGun.transform);
                        if (component3.CanScaleToMount && mount.CanThisRescale())
                        {
                            component3.ScaleToMount(mount);
                        }
                        component3.AttachToMount(mount, false);
                        if (component3 is Suppressor)
                        {
                            (component3 as Suppressor).AutoMountWell();
                        }
                        validIndexes.Add(savedGunComponent.Index);
                        toDealWith.RemoveAt(k);
                    }
                }
            }
            int trayIndex = 0;
            int itemIndex = 0;

            for (int l = 0; l < toMoveToTrays.Count; l++)
            {
                toMoveToTrays[l].transform.position = position + (float)itemIndex * 0.1f * Vector3.up;
                toMoveToTrays[l].transform.rotation = rotation;
                itemIndex++;
                trayIndex++;
                if (trayIndex > 2)
                {
                    trayIndex = 0;
                }
            }
            myGun.SetLoadedChambers(gun.LoadedRoundsInChambers);
            myGun.SetFromFlagList(gun.SavedFlags);
            myGun.transform.rotation = rotation;
            yield break;
        }