Exemplo n.º 1
0
        private GameObject PreparePrefab(GameObject prefab)
        {
            GameObject go = GameObject.Instantiate(prefab);

            ModPrefabCache.AddPrefab(go, false);
            return(go);
        }
Exemplo n.º 2
0
        public override IEnumerator GetGameObjectAsync(IOut <GameObject> gameObject)
        {
            Stillsuit s;

            if (prefab == null)
            {
                CoroutineTask <GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.ColdSuit, verbose: true);
                yield return(task);

                prefab = task.GetResult();
                //prefab.SetActive(false); // Keep the prefab inactive until we're done editing it.

                // Editing prefab
                if (prefab.TryGetComponent <Stillsuit>(out s))
                {
                    GameObject.DestroyImmediate(s);
                }
                prefab.EnsureComponent <SurvivalsuitBehaviour>();

                ModPrefabCache.AddPrefab(prefab, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)]
                                                         // but it can still be instantiated. [unlike with SetActive(false)]
            }

            // Despite the component being removed from the prefab above, testing shows that the Survival Suits still add the water packs when they should.
            // So we're going to force-remove it here, to be safe.
            GameObject go = GameObject.Instantiate(prefab);

            if (go.TryGetComponent <Stillsuit>(out s))
            {
                GameObject.DestroyImmediate(s);
            }
            gameObject.Set(go);
        }
Exemplo n.º 3
0
        public override IEnumerator GetGameObjectAsync(IOut <GameObject> gameObject)
        {
            CoroutineTask <GameObject> task;
            Oxygen oxy;

            if (prefab == null)
            {
                Log.LogDebug($"HighCapacityBooster.GetGameObjectAsync: getting SuitBoosterTank prefab");
                task = CraftData.GetPrefabForTechTypeAsync(TechType.SuitBoosterTank, verbose: true);
                yield return(task);

                prefab = GameObject.Instantiate(task.GetResult());
                ModPrefabCache.AddPrefab(prefab, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)] but it can still be instantiated.
                //HighCapacityBooster.prefab = prefab;
            }

            if (highCapTank == null)
            {
                Log.LogDebug($"HighCapacityBooster.GetGameObjectAsync: getting HighCapacityTank prefab");
                task = CraftData.GetPrefabForTechTypeAsync(TechType.HighCapacityTank, verbose: true);
                yield return(task);

                highCapTank = GameObject.Instantiate(task.GetResult()); // The "capacity expansion" code in Customise Your Oxygen can't run unless the thing is instantiated. The prefabs can't be altered.
                                                                        // So unless we instantiate, we only get default capacities.
                ModPrefabCache.AddPrefab(highCapTank, false);           // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)] but it can still be instantiated.
            }

            GameObject go            = GameObject.Instantiate(prefab);
            Oxygen     highCapOxygen = highCapTank.GetComponent <Oxygen>();

            //Oxygen highCapOxygen = task.GetResult().GetComponent<Oxygen>();
            if (highCapOxygen != null)
            {
                oxy = go.EnsureComponent <Oxygen>();
                if (oxy != null)
                {
                    float oxygenCapacity = highCapOxygen.oxygenCapacity;
                    Log.LogDebug($"Found Oxygen component with capacity of {oxygenCapacity} for prefab HighCapacityTank and existing oxygen capacity of {oxy.oxygenCapacity} for prefab HighCapacityBooster.");
                    oxy.oxygenCapacity = oxygenCapacity;
                }
                else
                {
                    Log.LogError($"Could not get Oxygen component of SuitBoosterTank while generating HighCapacityBooster");
                }

                GameObject.Destroy(highCapOxygen);
            }
            else
            {
                Log.LogError($"Could not get Oxygen component of HighCapacityTank while generating HighCapacityBooster");
            }

            float oxyCap = prefab.GetComponent <Oxygen>().oxygenCapacity;

            Log.LogDebug($"GameObject created with oxygenCapacity of {oxyCap}");
            gameObject.Set(go);
        }
Exemplo n.º 4
0
        private static GameObject SetupPrefab(GameObject activePrefab)
        {
            var obj = GameObject.Instantiate(activePrefab);

            if (obj == null)
            {
                return(null);
            }

            Knife knife = obj.GetComponent <Knife>();

            VibrobladeBehaviour blade = obj.EnsureComponent <VibrobladeBehaviour>();

            if (blade != null)
            {
                if (hbPrefab != null)
                {
                    HeatBlade hb = hbPrefab.GetComponent <HeatBlade>();
                    blade.fxControl    = hb.fxControl;
                    blade.vfxEventType = hb.vfxEventType;
                }
                if (knife != null)
                {
#if SUBNAUTICA_STABLE
                    blade.attackSound         = knife.attackSound;
                    blade.underwaterMissSound = knife.underwaterMissSound;
                    blade.surfaceMissSound    = knife.surfaceMissSound;
#endif
                    blade.mainCollider    = knife.mainCollider;
                    blade.drawSound       = knife.drawSound;
                    blade.firstUseSound   = knife.firstUseSound;
                    blade.hitBleederSound = knife.hitBleederSound;
                    if (hbPrefab == null)
                    {
                        blade.vfxEventType = knife.vfxEventType;
                    }
                    GameObject.DestroyImmediate(knife);
                }
                blade.attackDist    = 2f;
                blade.damageType    = DamageType.Normal;
                blade.socket        = PlayerTool.Socket.RightHand;
                blade.ikAimRightArm = true;
#if BELOWZERO
                blade.bleederDamage = 90f;
#endif
            }
            else
            {
#if !RELEASE
                Logger.Log(Logger.Level.Debug, $"Could not ensure VibrobladeBehaviour component in Vibroblade prefab");
#endif
            }

            ModPrefabCache.AddPrefab(obj, false);
            return(obj);
        }
        private GameObject PreparePrefab(GameObject thisPrefab)
        {
            if (thisPrefab == null)
            {
                Log.LogError("ModifyInstantiatedPrefab called with null prefab!");
                return(null);
            }

            var obj = GameObject.Instantiate(thisPrefab);

            MeshRenderer[]        meshRenderers        = obj.GetAllComponentsInChildren <MeshRenderer>();
            SkinnedMeshRenderer[] skinnedMeshRenderers = obj.GetAllComponentsInChildren <SkinnedMeshRenderer>();
            Color powerGlideColour = PowerglideBehaviour.PowerGlideColour;

            foreach (MeshRenderer mr in meshRenderers)
            {
                // MeshRenderers have the third-person mesh, apparently?
                if (mr.name.Contains("SeaGlide_01_damaged"))
                {
                    mr.material.color = powerGlideColour;
                }
            }

            foreach (SkinnedMeshRenderer smr in skinnedMeshRenderers)
            {
                if (smr.name.Contains("SeaGlide_geo"))
                {
                    smr.material.color = powerGlideColour;
                }
            }

            PrefabIdentifier prefabIdentifier = obj.EnsureComponent <PrefabIdentifier>();

            prefabIdentifier.ClassId = this.ClassID;
            obj.EnsureComponent <LargeWorldEntity>().cellLevel = LargeWorldEntity.CellLevel.VeryFar;
            obj.EnsureComponent <TechTag>().type = this.TechType;

            Pickupable pickupable = obj.EnsureComponent <Pickupable>();

            pickupable.isPickupable = false;

            ResourceTracker resourceTracker = obj.EnsureComponent <ResourceTracker>();

            resourceTracker.prefabIdentifier = prefabIdentifier;
            typeof(ResourceTracker).GetField("techType", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(resourceTracker, this.TechType);
            //resourceTracker.techType = this.TechType;
            resourceTracker.overrideTechType = TechType.Fragment;
            resourceTracker.techType         = Main.GetModTechType("PowerglideFragment");
            resourceTracker.rb         = obj.GetComponent <Rigidbody>();
            resourceTracker.pickupable = pickupable;

            ModPrefabCache.AddPrefab(obj, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)]
            // but it can still be instantiated. [unlike with SetActive(false)]

            return(obj);
        }
Exemplo n.º 6
0
 static GameObject _instantiate(GameObject gameObject, CopyOptions options)
 {
     if (options.HasFlag(CopyOptions.UseCache))
     {
         return(ModPrefabCache.AddPrefabCopy(gameObject, options.HasFlag(CopyOptions.AutoRemove)));
     }
     else
     {
         return(Object.Instantiate(gameObject));
     }
 }
        protected GameObject PreparePrefab(GameObject prefab)
        {
            GameObject obj = GameObject.Instantiate <GameObject>(prefab);

            // Editing prefab

            // Finalise prefab
            ModPrefabCache.AddPrefab(obj, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)]
                                                  // but it can still be instantiated. [unlike with SetActive(false)]
            return(obj);
        }
        public override IEnumerator GetGameObjectAsync(IOut <GameObject> gameObject)
        {
            if (processedPrefab == null)
            {
                CoroutineTask <GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.SeaglideFragment);
                yield return(task);

                GameObject prefab = GameObject.Instantiate(task.GetResult());

                MeshRenderer[]        meshRenderers        = prefab.GetAllComponentsInChildren <MeshRenderer>();
                SkinnedMeshRenderer[] skinnedMeshRenderers = prefab.GetAllComponentsInChildren <SkinnedMeshRenderer>();
                Color powerGlideColour = new Color(PowerglideEquipable.PowerglideColourR, PowerglideEquipable.PowerglideColourG, PowerglideEquipable.PowerglideColourB);

                foreach (MeshRenderer mr in meshRenderers)
                {
                    // MeshRenderers have the third-person mesh, apparently?
                    if (mr.name.Contains("SeaGlide_01_damaged"))
                    {
                        mr.material.color = powerGlideColour;
                    }
                }

                foreach (SkinnedMeshRenderer smr in skinnedMeshRenderers)
                {
                    if (smr.name.Contains("SeaGlide_geo"))
                    {
                        smr.material.color = powerGlideColour;
                    }
                }

                PrefabIdentifier prefabIdentifier = prefab.GetComponent <PrefabIdentifier>();
                prefabIdentifier.ClassId = this.ClassID;
                prefab.GetComponent <LargeWorldEntity>().cellLevel = LargeWorldEntity.CellLevel.VeryFar;
                prefab.EnsureComponent <TechTag>().type            = this.TechType;

                Pickupable pickupable = prefab.GetComponent <Pickupable>();
                pickupable.isPickupable = false;

                ResourceTracker resourceTracker = prefab.EnsureComponent <ResourceTracker>();
                resourceTracker.prefabIdentifier = prefabIdentifier;
                typeof(ResourceTracker).GetField("techType", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(resourceTracker, this.TechType);
                //resourceTracker.techType = this.TechType;
                resourceTracker.overrideTechType = TechType.Fragment;
                resourceTracker.rb         = prefab.GetComponent <Rigidbody>();
                resourceTracker.pickupable = pickupable;

                prefab.SetActive(true);
                processedPrefab = prefab;
                ModPrefabCache.AddPrefab(processedPrefab, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)]
                // but it can still be instantiated. [unlike with SetActive(false)]
            }

            gameObject.Set(processedPrefab);
        }
        public override IEnumerator GetGameObjectAsync(IOut<GameObject> gameObject)
        {
            if (prefab == null)
            {
                CoroutineTask<GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.HoverbikeJumpModule);
                yield return task;
                prefab = GameObject.Instantiate<GameObject>(task.GetResult());
                ModPrefabCache.AddPrefab(prefab, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)]
                                                         // but it can still be instantiated. [unlike with SetActive(false)]
            }

            gameObject.Set(GameObject.Instantiate(prefab));
        }
Exemplo n.º 10
0
        public override IEnumerator GetGameObjectAsync(IOut <GameObject> gameObject)
        {
            if (prefab == null)
            {
                var task = CraftData.GetPrefabForTechTypeAsync(TechType.MapRoomHUDChip);
                yield return(task);

                prefab = GameObject.Instantiate(task.GetResult());
                ModPrefabCache.AddPrefab(prefab, false);                 // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)] but it can still be instantiated.
            }

            gameObject.Set(prefab);
        }
Exemplo n.º 11
0
        public override GameObject GetGameObject()
        {
            System.Reflection.MethodBase thisMethod = System.Reflection.MethodBase.GetCurrentMethod();
            Log.LogDebug($"{thisMethod.ReflectedType.Name}.{thisMethod.Name}: begin");
            if (prefab == null)
            {
                prefab = GameObject.Instantiate(CraftData.GetPrefabForTechType(TechType.MapRoomHUDChip));
            }

            ModPrefabCache.AddPrefab(prefab);

            Log.LogDebug($"{thisMethod.ReflectedType.Name}.{thisMethod.Name}: end");
            return(prefab);
        }
        private GameObject InstantiateAndModifyGameObject(GameObject thisPrefab)
        {
            GameObject obj = GameObject.Instantiate(thisPrefab);

            // Editing prefab
            if (obj.TryGetComponent <Stillsuit>(out Stillsuit s))
            {
                GameObject.DestroyImmediate(s);
            }
            obj.EnsureComponent <SurvivalsuitBehaviour>();
            ModPrefabCache.AddPrefab(obj, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)] but it can still be instantiated.

            return(obj);
        }
        public override IEnumerator GetGameObjectAsync(IOut <GameObject> gameObject)
        {
            if (prefab == null)
            {
                CoroutineTask <GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.SeaTruckUpgradeEnergyEfficiency);
                yield return(task);

                prefab = GameObject.Instantiate <GameObject>(task.GetResult());
                // The code is handled by the SeatruckUpdater component, rather than anything here.
                ModPrefabCache.AddPrefab(prefab, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)]
                                                         // but it can still be instantiated. [unlike with SetActive(false)]
            }

            gameObject.Set(GameObject.Instantiate(prefab));
        }
Exemplo n.º 14
0
        public override IEnumerator GetGameObjectAsync(IOut <GameObject> gameObject)
        {
            if (prefab == null)
            {
                CoroutineTask <GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.ColdSuitGloves, verbose: true);
                yield return(task);

                prefab = GameObject.Instantiate(task.GetResult());
                ModPrefabCache.AddPrefab(prefab, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)] but it can still be instantiated.
            }

            GameObject go = GameObject.Instantiate(prefab);

            gameObject.Set(go);
        }
Exemplo n.º 15
0
        public override GameObject GetGameObject()
        {
            GameObject prefab;

            if (!prefabs.TryGetValue(this.TechType, out prefab))
            {
                prefab = CraftData.GetPrefabForTechType(thisBaseTank)
                ;
                //prefab.EnsureComponent<AutoRemover>();
                prefabs.Add(this.TechType, prefab);
                ModPrefabCache.AddPrefab(prefab, false);                 // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)]
                // but it can still be instantiated. [unlike with SetActive(false)]
                // Clarification: An inactive prefab can still be instantiated, but it will be instantiated as an inactive GameObject. Obviously, not that useful to us here.
                // But since the prefab isn't *set* inactive, we can instantiate active objects with it, even though the prefab is effectively-inactive.
            }

            return(prefab);
        }
Exemplo n.º 16
0
        public override IEnumerator GetGameObjectAsync(IOut <GameObject> gameObject)
        {
            GameObject prefab;

            if (!prefabs.TryGetValue(this.TechType, out prefab))
            {
                //var task = CraftData.GetPrefabForTechTypeAsync(TechType.Tank);
                var task = CraftData.GetPrefabForTechTypeAsync(thisBaseTank);
                yield return(task);

                prefab = task.GetResult();
                //prefab.EnsureComponent<AutoRemover>();
                prefabs.Add(this.TechType, prefab);
                ModPrefabCache.AddPrefab(prefab, false);                 // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)]
                // but it can still be instantiated. [unlike with SetActive(false)]
            }

            gameObject.Set(GameObject.Instantiate(prefab));
        }
        public override IEnumerator GetGameObjectAsync(IOut <GameObject> gameObject)
        {
            if (prefab == null)
            {
                CoroutineTask <GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.FrozenCreatureAntidote);
                yield return(task);

                prefab = GameObject.Instantiate(task.GetResult());
                if (prefab.TryGetComponent <CompleteGoalOnExamine>(out CompleteGoalOnExamine cgoe))
                {
                    GameObject.DestroyImmediate(cgoe);
                }
                ModPrefabCache.AddPrefab(prefab, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)]
                                                         // but it can still be instantiated. [unlike with SetActive(false)]
            }

            var obj = GameObject.Instantiate(prefab);

            gameObject.Set(obj);
        }
Exemplo n.º 18
0
        public override IEnumerator GetGameObjectAsync(IOut <GameObject> gameObject)
        {
            if (prefab == null)
            {
                CoroutineTask <GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.Stillsuit, verbose: true);
                yield return(task);

                prefab = GameObject.Instantiate(task.GetResult());

                // Editing prefab
                GameObject.DestroyImmediate(prefab.GetComponent <Stillsuit>());
                prefab.EnsureComponent <SurvivalsuitBehaviour>();

                ModPrefabCache.AddPrefab(prefab, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)] but it can still be instantiated.
            }

            GameObject go = GameObject.Instantiate(prefab);

            gameObject.Set(go);
        }
Exemplo n.º 19
0
        public override IEnumerator GetGameObjectAsync(IOut <GameObject> gameObject)
        {
            if (prefab == null)
            {
                CoroutineTask <GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.CoralChunk);
                yield return(task);

                prefab = GameObject.Instantiate(task.GetResult());
                ModPrefabCache.AddPrefab(prefab, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)]
                                                         // but it can still be instantiated. [unlike with SetActive(false)]
            }

            // In BZ, the coral chunk has faulty collision. We fix it here.
            var obj = GameObject.Instantiate(prefab);

            if (obj.TryGetComponent <LargeWorldEntity>(out LargeWorldEntity largeWorldEntity))
            {
                obj.EnsureComponent <WorldForces>().useRigidbody = largeWorldEntity.GetComponent <Rigidbody>();
            }
            gameObject.Set(obj);
        }
        public override IEnumerator GetGameObjectAsync(IOut <GameObject> gameObject)
        {
            if (prefab == null)
            {
                CoroutineTask <GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.Seaglide, verbose: true);
                yield return(task);

                prefab = GameObject.Instantiate(task.GetResult());
                prefab.EnsureComponent <PowerglideBehaviour>();

                /*
                 * MeshRenderer[] meshRenderers = prefab.GetAllComponentsInChildren<MeshRenderer>();
                 * SkinnedMeshRenderer[] skinnedMeshRenderers = prefab.GetAllComponentsInChildren<SkinnedMeshRenderer>();
                 * Color powerGlideColour = new Color(PowerglideColourR, PowerglideColourG, PowerglideColourB);
                 *
                 * foreach (MeshRenderer mr in meshRenderers)
                 * {
                 *      // MeshRenderers have the third-person mesh, apparently?
                 *      if (mr.name.Contains("SeaGlide_01_TP"))
                 *      {
                 *              mr.material.color = powerGlideColour;
                 *      }
                 * }
                 *
                 * foreach (SkinnedMeshRenderer smr in skinnedMeshRenderers)
                 * {
                 *      if (smr.name.Contains("SeaGlide_Geo"))
                 *      {
                 *              smr.material.color = powerGlideColour;
                 *      }
                 * }
                 */
                ModPrefabCache.AddPrefab(prefab, false);                 // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)] but it can still be instantiated.
            }

            GameObject go = GameObject.Instantiate(prefab);

            go.EnsureComponent <PowerglideBehaviour>();
            gameObject.Set(go);
        }
Exemplo n.º 21
0
        protected virtual IEnumerator PostPatchSetup()
        {
            bool bWaiting = true;

            while (bWaiting)
            {
                if (icon == null || icon == SpriteManager.defaultSprite)
                {
                    icon = SpriteManager.Get(TechType.HighCapacityTank);
                }
                else
                {
                    bWaiting = false;
                }

                yield return(new WaitForSecondsRealtime(0.5f));
            }

            CoroutineTask <GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.HighCapacityTank);

            yield return(task);

            var highCapPrefab = task.GetResult();

            if (highCapPrefab != null)
            {
                highCapTank = GameObject.Instantiate(highCapPrefab);
                ModPrefabCache.AddPrefab(highCapTank, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)] but it can still be instantiated.
            }
            else
            {
                Log.LogError($"Failed getting prefab for HighCapacityTank");
            }

            Main.AddCustomOxyExclusion(this.TechType, true, true);
            Main.AddCustomOxyTank(this.TechType, -1f, icon);
        }
Exemplo n.º 22
0
        public override IEnumerator GetGameObjectAsync(IOut <GameObject> gameObject)
        {
            if (prefab == null)
            {
                CoroutineTask <GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.ExosuitDrillArmModule);
                yield return(task);

                prefab = GameObject.Instantiate <GameObject>(task.GetResult());

                // Adapted from Senna's SeaTruckArms mod
                task = CraftData.GetPrefabForTechTypeAsync(TechType.Exosuit, verbose: true);
                yield return(task);

                if (task.GetResult().TryGetComponent <Exosuit>(out Exosuit exosuit))
                {
                    GameObject armPrefab = null;
                    for (int i = 0; i < exosuit.armPrefabs.Length; i++)
                    {
                        if (exosuit.armPrefabs[i].techType == TechType.ExosuitClawArmModule)
                        {
                            //Log.LogDebug($"Found claw arm prefab in Exosuit armPrefabs at index {i}");
                            armPrefab = exosuit.armPrefabs[i].prefab;
                            break;
                        }
                    }

                    if (armPrefab != null)
                    {
                        SkinnedMeshRenderer smr = armPrefab.GetComponentInChildren <SkinnedMeshRenderer>();
                        Mesh clawMesh           = smr.sharedMesh;

                        MeshFilter mf = prefab.GetComponentInChildren <MeshFilter>();
                        mf.sharedMesh      = Object.Instantiate(clawMesh);
                        mf.sharedMesh.name = "exosuit_lightningclaw_hand_geo";

                        MeshRenderer mr = prefab.GetComponentInChildren <MeshRenderer>();
                        mr.materials = (Material[])smr.materials.Clone();

                        prefab.transform.Find("model/exosuit_rig_armLeft:exosuit_drill_geo").gameObject.name = "exosuit_lightningclaw_arm_geo";

                        Object.Destroy(prefab.GetComponentInChildren <CapsuleCollider>());

                        BoxCollider bc_1 = prefab.FindChild("collider").AddComponent <BoxCollider>();

                        bc_1.size   = new Vector3(1.29f, 0.33f, 0.42f);
                        bc_1.center = new Vector3(-0.53f, 0f, 0.04f);

                        GameObject collider2 = new GameObject("collider2");
                        collider2.transform.SetParent(prefab.transform, false);
                        collider2.transform.localPosition = new Vector3(-1.88f, 0.07f, 0.50f);
                        collider2.transform.localRotation = Quaternion.Euler(0, 34, 0);

                        BoxCollider bc_2 = collider2.AddComponent <BoxCollider>();
                        bc_2.size   = new Vector3(1.06f, 0.23f, 0.31f);
                        bc_2.center = new Vector3(0, -0.08f, 0);

                        prefab.transform.localScale = new Vector3(0.8f, 0.8f, 0.8f);

                        GameObject.DestroyImmediate(prefab.GetComponent <ExosuitClawArm>());
                        GameObject.DestroyImmediate(prefab.GetComponent <ExosuitDrillArm>());
                        prefab.AddComponent <ExosuitLightningClaw>();
                    }
                    else
                    {
                        Log.LogDebug($"Failed to find arm prefab in Exosuit prefab");
                    }

                    ModPrefabCache.AddPrefab(prefab, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)]
                                                             // but it can still be instantiated. [unlike with SetActive(false)]
                }
                else
                {
                    Log.LogDebug($"Failed to find Exosuit prefab");
                }
            }

            gameObject.Set(GameObject.Instantiate(prefab));
        }
        public override IEnumerator GetGameObjectAsync(IOut<GameObject> gameObject)
        {
            // We're not using a separate PreparePrefab() method, because this object only exists in BelowZero.
            // In the event 

            CoroutineTask<GameObject> task;
            Oxygen oxy;
            if (Main.HighCapacityTankPrefab == null)
            {
                Log.LogDebug($"HighCapacityBooster.GetGameObjectAsync: getting HighCapacityTank prefab");
                task = CraftData.GetPrefabForTechTypeAsync(TechType.HighCapacityTank, verbose: true);
                yield return task;
                Main.HighCapacityTankPrefab = GameObject.Instantiate(task.GetResult()); // The "capacity expansion" code in Customise Your Oxygen can't run unless the thing is instantiated. The prefabs can't be altered.
                                                                                        // So unless we instantiate, we only get default capacities.
                ModPrefabCache.AddPrefab(Main.HighCapacityTankPrefab, false);
            }

            if (prefab == null)
            {
                Log.LogDebug($"HighCapacityBooster.GetGameObjectAsync: getting SuitBoosterTank prefab");
                task = CraftData.GetPrefabForTechTypeAsync(TechType.SuitBoosterTank, verbose: true);
                yield return task;

                prefab = GameObject.Instantiate(task.GetResult());
                ModPrefabCache.AddPrefab(prefab, false); // This doesn't actually do any caching, but it does disable the prefab without "disabling" it - the prefab doesn't show up in the world [as with SetActive(false)] but it can still be instantiated.

                //GameObject go = GameObject.Instantiate(prefab);
                Oxygen highCapOxygen = Main.HighCapacityTankPrefab.GetComponent<Oxygen>();
                //Oxygen highCapOxygen = task.GetResult().GetComponent<Oxygen>();
                if (highCapOxygen != null)
                {
                    oxy = prefab.EnsureComponent<Oxygen>();
                    if (oxy != null)
                    {
                        float oxygenCapacity = highCapOxygen.oxygenCapacity;
                        Log.LogDebug($"Found Oxygen component with capacity of {oxygenCapacity} for prefab HighCapacityTank and existing oxygen capacity of {oxy.oxygenCapacity} for prefab IonBoosterTank.");
                        oxy.oxygenCapacity = oxygenCapacity;
                    }
                    else
                    {
                        Log.LogError($"Could not get Oxygen component of SuitBoosterTank while generating IonBoosterTank");
                    }
                }
                else
                    Log.LogError($"Could not get Oxygen component of HighCapacityTank while generating IonBoosterTank");

                var booster = prefab.GetComponent<SuitBoosterTank>();
                if (booster != null)
                {
                    booster.boostOxygenUsePerSecond = boostOxygenUsePerSecond;
                }
                else
                {
                    Log.LogError($"Could not get SuitBoosterTank component of SuitBoosterTank prefab while generating IonBoosterTank");
                }
            }

            oxy = prefab.GetComponent<Oxygen>();
            float oxyCap = oxy != null ? oxy.oxygenCapacity : -1f;
            Log.LogDebug($"IonBoosterTank created with oxygenCapacity of {oxyCap}");
            var postBooster = prefab.GetComponent<SuitBoosterTank>();
            if (postBooster != null)
            {
                if (postBooster.boostOxygenUsePerSecond != boostOxygenUsePerSecond)
                {
                    Log.LogDebug($"Editing SuitBoosterTnk component");
                    postBooster.boostOxygenUsePerSecond = boostOxygenUsePerSecond;
                }
            }
            else
            {
                Log.LogError($"Could not get SuitBoosterTank component of SuitBoosterTank prefab while generating IonBoosterTank");
            }

            gameObject.Set(prefab);
        }