private static IEnumerator SpawnCreature(WaterPark waterPark, WaterParkCreature parkCreature, ItemsContainer container) { CoroutineTask <GameObject> task = CraftData.GetPrefabForTechTypeAsync(parkCreature.pickupable.GetTechType(), false); yield return(task); GameObject prefab = task.GetResult(); prefab.SetActive(false); GameObject gameObject = GameObject.Instantiate(prefab); Pickupable pickupable = gameObject.EnsureComponent <Pickupable>(); #if SUBNAUTICA_EXP TaskResult <Pickupable> taskResult = new TaskResult <Pickupable>(); yield return(pickupable.PickupAsync(taskResult, false)); pickupable = taskResult.Get(); #else pickupable.Pickup(false); #endif container.AddItem(pickupable); yield break; }
public static bool TryBreedIntoAlterraGen(WaterPark waterPark, TechType parkCreatureTechType, WaterParkCreature parkCreature) { var componentInParent = waterPark != null?waterPark.gameObject.GetComponentInParent <SubRoot>() : null; var AlterraGens = componentInParent != null ? componentInParent.gameObject.GetComponentsInChildren <IFCSStorage>() : null; if (AlterraGens is null) { return(false); } foreach (var storage in AlterraGens) { if (!storage.GetType().Name.Contains("AlterraGen") || !storage.IsAllowedToAdd(parkCreature.pickupable, false)) { continue; } CoroutineHost.StartCoroutine(AddItemToAlterraGen(parkCreatureTechType, storage)); return(true); } return(false); }
private void AssignToWaterPark(String waterParkGuid, Pickupable pickupable) { GameObject waterParkGo = GuidHelper.RequireObjectFrom(waterParkGuid); WaterPark waterPark = waterParkGo.RequireComponent <WaterPark>(); waterPark.AddItem(pickupable); }
protected override void SpawnPostProcess(Base latestBase, Int3 latestCell, GameObject finishedPiece) { NitroxId pieceId = NitroxEntity.GetId(finishedPiece); WaterParkPiece waterParkPiece = finishedPiece.GetComponent <WaterParkPiece>(); if (!waterParkPiece) { // The BaseWater has multiple base pieces, but only one of them (the bottom) contains the WaterParkPiece component... return; } WaterPark waterPark = waterParkPiece.GetWaterParkModule(); Validate.NotNull(waterPark, "WaterParkPiece without WaterParkModule?!?"); // assuming there could be multiple pieces sharing the same waterpark we only create an ID if there is none. NitroxEntity waterEntity = waterPark.gameObject.GetComponent <NitroxEntity>(); if (!waterEntity) { NitroxId newWaterparkId = pieceId.Increment(); NitroxEntity.SetNewId(waterPark.gameObject, newWaterparkId); NitroxId newPlanterId = newWaterparkId.Increment(); NitroxEntity.SetNewId(waterPark.planter.gameObject, newPlanterId); Log.Debug($"BaseRoomWaterParkProcessor: Created new Waterpark {newWaterparkId} and Planter {newPlanterId}"); } }
// The next two functions could potentially reside outside of this specific serializer. // They only happen to be in here because dropped items use this code path. private void AssignToWaterPark(GameObject gameObject, string waterParkGuid) { Pickupable pickupable = gameObject.RequireComponent <Pickupable>(); GameObject waterParkGo = GuidHelper.RequireObjectFrom(waterParkGuid); WaterPark waterPark = waterParkGo.RequireComponent <WaterPark>(); waterPark.AddItem(pickupable); }
// The next two functions could potentially reside outside of this specific serializer. // They only happen to be in here because dropped items use this code path. private void AssignToWaterPark(GameObject gameObject, NitroxId waterParkId) { Pickupable pickupable = gameObject.RequireComponent <Pickupable>(); GameObject waterParkGo = NitroxEntity.RequireObjectFrom(waterParkId); WaterPark waterPark = waterParkGo.RequireComponent <WaterPark>(); waterPark.AddItem(pickupable); }
public static void Prefix(WaterPark __instance) { #if BZ if (__instance is LargeRoomWaterPark) { __instance.wpPieceCapacity = Main.config.LargeWaterParkSize; } else #endif __instance.wpPieceCapacity = Main.config.WaterParkSize; }
private static IEnumerator SpawnCreature(WaterPark waterPark, TechType parkCreatureTechType, ItemsContainer container) { var task = CraftData.GetPrefabForTechTypeAsync(parkCreatureTechType, false); yield return(task); var prefab = task.GetResult(); if (prefab == null) { yield break; } prefab.SetActive(false); var gameObject = Object.Instantiate(prefab); if (container is not null) { var pickupable = gameObject.EnsureComponent <Pickupable>(); #if SUBNAUTICA_EXP TaskResult <Pickupable> taskResult = new TaskResult <Pickupable>(); yield return(pickupable.PickupAsync(taskResult, false)); pickupable = taskResult.Get(); #else pickupable.Pickup(false); #endif gameObject.SetActive(false); container.AddItem(pickupable); yield break; } var spawnPoint = waterPark.transform.position + (Random.insideUnitSphere * 50); var @base = #if SN1 waterPark.GetComponentInParent <Base>(); #elif BZ waterPark.hostBase; #endif while (Vector3.Distance(@base.GetClosestPoint(spawnPoint), spawnPoint) < 25 || spawnPoint.y >= 0) { yield return(null); spawnPoint = @base.GetClosestPoint(spawnPoint) + (Random.insideUnitSphere * 50); } gameObject.transform.SetPositionAndRotation(spawnPoint, Quaternion.identity); gameObject.SetActive(true); }
public static void Postfix(WaterPark __instance, WaterParkCreature creature) { if (!__instance.items.Contains(creature) || __instance.HasFreeSpace()) { return; } List <BaseBioReactor> baseBioReactors = __instance.gameObject.GetComponentInParent <SubRoot>().gameObject.GetComponentsInChildren <BaseBioReactor>().ToList(); bool hasBred = false; foreach (WaterParkItem waterParkItem in __instance.items) { WaterParkCreature parkCreature = waterParkItem as WaterParkCreature; if (parkCreature != null && parkCreature != creature && parkCreature.GetCanBreed() && parkCreature.pickupable.GetTechType() == creature.pickupable.GetTechType() && !parkCreature.pickupable.GetTechType().ToString().Contains("Egg")) { foreach (BaseBioReactor baseBioReactor in baseBioReactors) { if (baseBioReactor.container.HasRoomFor(parkCreature.pickupable)) { creature.ResetBreedTime(); parkCreature.ResetBreedTime(); GameObject gameObject = CraftData.InstantiateFromPrefab(CraftData.GetTechType(parkCreature.data.eggOrChildPrefab), false); gameObject.SetActive(false); baseBioReactor.container.AddItem(gameObject.EnsureComponent <Pickupable>()); hasBred = true; break; } } if (!hasBred && Config.OverFlowIntoOcean && parkCreature.data.isPickupableOutside) { creature.ResetBreedTime(); parkCreature.ResetBreedTime(); if (count > Config.WaterParkSize) { GameObject gameObject = CraftData.InstantiateFromPrefab(CraftData.GetTechType(parkCreature.gameObject), false); gameObject.transform.position = __instance.gameObject.GetComponentInParent <SubRoot>().transform.position + new Vector3(Random.Range(-30, 30), Random.Range(-2, 30), Random.Range(-30, 30)); gameObject.SetActive(true); count = 0; } else { count++; } } break; } } }
public static void Postfix(WaterPark __instance, WaterParkCreature creature) { List <WaterParkItem> items = __instance.items; if (!items.Contains(creature) || __instance.HasFreeSpace() || BaseBioReactor.GetCharge(creature.pickupable.GetTechType()) == -1) { return; } List <BaseBioReactor> baseBioReactors = __instance.gameObject.GetComponentInParent <SubRoot>().gameObject.GetComponentsInChildren <BaseBioReactor>().ToList(); bool hasBred = false; foreach (WaterParkItem waterParkItem in items) { var parkCreature = waterParkItem as WaterParkCreature; TechType parkCreatureTechType = parkCreature?.pickupable?.GetTechType() ?? TechType.None; if (parkCreature != null && parkCreature != creature && parkCreature.GetCanBreed() && parkCreatureTechType == creature.pickupable.GetTechType() && !parkCreatureTechType.ToString().Contains("Egg")) { if (BaseBioReactor.GetCharge(parkCreatureTechType) > -1) { if (QModServices.Main.ModPresent("FCSEnergySolutions")) { hasBred = AGT.TryBreedIntoAlterraGen(__instance, parkCreatureTechType, parkCreature); } if (!hasBred) { foreach (BaseBioReactor baseBioReactor in baseBioReactors) { if (baseBioReactor.container.HasRoomFor(parkCreature.pickupable)) { creature.ResetBreedTime(); parkCreature.ResetBreedTime(); hasBred = true; CoroutineHost.StartCoroutine(SpawnCreature(__instance, parkCreature, baseBioReactor.container)); break; } } } } creature.ResetBreedTime(); parkCreature.ResetBreedTime(); break; } } }
private Optional <NitroxId> GetCurrentWaterParkId() { Player player = Utils.GetLocalPlayer().GetComponent <Player>(); if (player != null) { WaterPark currentWaterPark = player.currentWaterPark; if (currentWaterPark != null) { NitroxId waterParkId = NitroxEntity.GetId(currentWaterPark.gameObject); return(Optional.Of(waterParkId)); } } return(Optional.Empty); }
private Optional <String> GetCurrentWaterParkGuid() { Player player = Utils.GetLocalPlayer().GetComponent <Player>(); if (player != null) { WaterPark currentWaterPark = player.currentWaterPark; if (currentWaterPark != null) { String waterParkGuid = GuidHelper.GetGuid(currentWaterPark.gameObject); return(Optional <String> .Of(waterParkGuid)); } } return(Optional <String> .Empty()); }
public static bool TryBreedIntoAlterraGen(WaterPark waterPark, TechType parkCreatureTechType, WaterParkCreature parkCreature) { var AlterraGens = waterPark?.gameObject?.GetComponentInParent <SubRoot>()?.gameObject?.GetComponentsInChildren <IFCSStorage>(); if (AlterraGens is null) { return(false); } foreach (IFCSStorage storage in AlterraGens) { if (storage.GetType().Name.Contains("AlterraGen") && storage.IsAllowedToAdd(parkCreature.pickupable, false)) { CoroutineHost.StartCoroutine(AddItemToAlterraGen(parkCreatureTechType, storage)); return(true); } } return(false); }
private void AssignToWaterPark(String waterParkGuid, Pickupable pickupable) { Optional <GameObject> opWaterPark = GuidHelper.GetObjectFrom(waterParkGuid); if (opWaterPark.IsPresent()) { WaterPark waterPark = opWaterPark.Get().GetComponent <WaterPark>(); if (waterPark != null) { waterPark.AddItem(pickupable); } else { Console.WriteLine("Could not find water park component on that game object"); } } else { Console.WriteLine("Could not locate water park with guid: " + waterParkGuid); } }
public static void Postfix(WaterPark __instance) { PowerSource powerSource = __instance.gameObject.GetComponent <PowerSource>(); int numberOfShockers = __instance.items.FindAll((WaterParkItem item) => item.pickupable.GetTechType() == TechType.Shocker).Count; if (powerSource == null) { powerSource = __instance.gameObject.AddComponent <PowerSource>(); powerSource.maxPower = 100 * numberOfShockers; powerSource.power = PlayerPrefs.GetFloat($"PowerSource:{__instance.GetInstanceID()}", 0f); } else { powerSource.maxPower = 100 * numberOfShockers; } if (powerSource.GetPower() > powerSource.GetMaxPower()) { powerSource.power = powerSource.maxPower; } Config.PowerValues[$"PowerSource:{__instance.GetInstanceID()}"] = powerSource.GetPower(); }
public static bool Prefix(WaterPark waterPark, Vector3 position) { return(waterPark.IsPointInside(position)); }
public static void Postfix(WaterPark __instance) { List <WaterParkItem> powerCreatures = new List <WaterParkItem>(); float maxPower = 0; if (cachedItems.TryGetValue(__instance, out List <WaterParkItem> items) && items.Count == __instance.items.Count && cachedPowerCreatures.ContainsKey(__instance)) { powerCreatures.AddRange(cachedPowerCreatures[__instance]); foreach (var creature in cachedPowerCreatures[__instance]) { if (!creature.gameObject.TryGetComponent(out LiveMixin liveMixin) || !liveMixin.IsAlive()) { powerCreatures.Remove(creature); } } foreach (KeyValuePair <TechType, float> pair in Main.config.CreaturePowerGeneration) { List <WaterParkItem> creatures = __instance.items.FindAll((WaterParkItem item) => item.pickupable.GetTechType() == pair.Key) ?? new List <WaterParkItem>(); if (creatures.Count > 0) { maxPower += 500 * pair.Value * creatures.Count; } } cachedPowerCreatures[__instance] = powerCreatures; } else { foreach (KeyValuePair <TechType, float> pair in Main.config.CreaturePowerGeneration) { List <WaterParkItem> creatures = __instance.items.FindAll((WaterParkItem item) => item.pickupable.GetTechType() == pair.Key && (item.GetComponent <LiveMixin>()?.IsAlive() ?? false)) ?? new List <WaterParkItem>(); if (creatures.Count > 0) { maxPower += 500 * pair.Value * creatures.Count; powerCreatures.AddRange(creatures); } } cachedItems[__instance] = __instance.items; cachedPowerCreatures[__instance] = powerCreatures; } PowerSource powerSource = __instance?.itemsRoot?.gameObject?.GetComponent <PowerSource>(); if (powerSource is null) { powerSource = __instance?.itemsRoot?.gameObject?.AddComponent <PowerSource>(); powerSource.maxPower = maxPower; powerSource.power = Main.config.PowerValues.GetOrDefault($"PowerSource:{__instance.GetInstanceID()}", 0f); } else { if (powerSource.maxPower != maxPower) { powerSource.maxPower = maxPower; } if (powerSource.power > powerSource.maxPower) { powerSource.power = powerSource.maxPower; } Main.config.PowerValues[$"PowerSource:{__instance.GetInstanceID()}"] = powerSource.power; } timeSinceLastPositionCheck += Time.deltaTime; if (timeSinceLastPositionCheck > 0.5f) { foreach (WaterParkItem waterParkItem in __instance.items) { if (!__instance.IsPointInside(waterParkItem.transform.position)) { Vector3 position = waterParkItem.transform.position; __instance.EnsurePointIsInside(ref position); waterParkItem.transform.position = position; } } timeSinceLastPositionCheck = 0; } }
public static void Prefix(WaterPark __instance) { __instance.wpPieceCapacity = Main.Config.WaterParkSize; }
public static void Postfix(WaterPark __instance, WaterParkCreature creature) { if (!Main.Config.AlterraGenOverflow && !Main.Config.BioReactorOverflow && !Main.Config.OceanBreeding) { return; } var items = __instance.items; var techType = creature.pickupable.GetTechType(); if (!items.Contains(creature) || __instance.HasFreeSpace() || BaseBioReactor.GetCharge(techType) <= 0f) { return; } var hasBred = false; foreach (var waterParkItem in items) { var parkCreature = waterParkItem as WaterParkCreature; var parkCreatureTechType = parkCreature is not null && parkCreature.pickupable != null?parkCreature.pickupable.GetTechType() : TechType.None; if (parkCreature == null || parkCreature == creature || !parkCreature.GetCanBreed() || parkCreatureTechType != techType || parkCreatureTechType.ToString().Contains("Egg")) { continue; } if (BaseBioReactor.GetCharge(parkCreatureTechType) > -1) { if (Main.Config.AlterraGenOverflow && !Main.Config.AlterraGenBlackList.Contains(parkCreatureTechType) && QModServices.Main.ModPresent("FCSEnergySolutions")) { hasBred = AGT.TryBreedIntoAlterraGen(__instance, parkCreatureTechType, parkCreature); } if (Main.Config.BioReactorOverflow && !Main.Config.BioReactorBlackList.Contains(parkCreatureTechType) && !hasBred) { var baseBioReactors = __instance.gameObject.GetComponentInParent <SubRoot>()?.gameObject .GetComponentsInChildren <BaseBioReactor>() ?.Where(baseBioReactor => baseBioReactor.container.HasRoomFor(parkCreature.pickupable)) .ToList() ?? new List <BaseBioReactor>(); if (baseBioReactors.Count > 0) { hasBred = true; baseBioReactors.Shuffle(); var baseBioReactor = baseBioReactors.First(); CoroutineHost.StartCoroutine(SpawnCreature(__instance, parkCreatureTechType, baseBioReactor.container)); } } if (Main.Config.OceanBreeding && Main.Config.OceanBreedWhiteList.Contains(parkCreatureTechType) && !hasBred && __instance.transform.position.y < 0) { CoroutineHost.StartCoroutine(SpawnCreature(__instance, parkCreatureTechType, null)); hasBred = true; } } if (hasBred) { creature.ResetBreedTime(); parkCreature.ResetBreedTime(); } break; } }
public static void Postfix(Player __instance) { PlayerTool heldTool = Inventory.main.GetHeldTool(); Vehicle vehicle = __instance.GetVehicle(); Pickupable module = vehicle?.GetSlotItem(vehicle.GetActiveSlotID())?.item; bool builderCheck = heldTool?.pickupable?.GetTechType() == TechType.Builder; bool builderModuleCheck = module != null && TechTypeHandler.TryGetModdedTechType("BuilderModule", out TechType modTechType) && module.GetTechType() == modTechType; string msg1 = $"Attach as target override = {Main.config.AttachToTarget}"; ErrorMessage._Message emsg = ErrorMessage.main.GetExistingMessage(msg1); string msg2 = $"Full Override = {Main.config.FullOverride}"; ErrorMessage._Message emsg2 = ErrorMessage.main.GetExistingMessage(msg2); if (DevConsole.instance != null && !DevConsole.instance.state && (builderCheck || builderModuleCheck)) { if (Input.GetKeyDown(Main.config.AttachToTargetToggle)) { Main.config.AttachToTarget = !Main.config.AttachToTarget; msg1 = $"Attach as target override = {Main.config.AttachToTarget}"; } if (Input.GetKeyDown(Main.config.FullOverrideToggle)) { Main.config.FullOverride = !Main.config.FullOverride; msg2 = $"Full Override = {Main.config.FullOverride}"; } if (emsg != null) { emsg.messageText = msg1; emsg.entry.text = msg1; if (emsg.timeEnd <= Time.time + 1f) { emsg.timeEnd += Time.deltaTime; } } else { ErrorMessage.AddMessage(msg1); } if (emsg2 != null) { emsg2.messageText = msg2; emsg2.entry.text = msg2; if (emsg2.timeEnd <= Time.time + 1f) { emsg2.timeEnd += Time.deltaTime; } } else { ErrorMessage.AddMessage(msg2); } } else if (Main.config.AttachToTarget || Main.config.FullOverride) { Main.config.AttachToTarget = false; Main.config.FullOverride = false; if (emsg != null) { emsg.timeEnd = Time.time; } if (emsg2 != null) { emsg2.timeEnd = Time.time; } } WaterPark waterPark = __instance?.currentWaterPark; if (waterPark?.GetComponentInParent <Creature>() != null) { Vector3 vector3 = __instance.currentWaterPark.transform.position; __instance.SetPosition(vector3); string msg3 = $"Press {GameInput.GetBinding(GameInput.GetPrimaryDevice(), GameInput.Button.Exit, GameInput.BindingSet.Primary)} to exit waterpark if you cant reach the exit."; ErrorMessage._Message emsg3 = ErrorMessage.main.GetExistingMessage(msg3); if (emsg3 != null && emsg3.timeEnd <= Time.time + 1f) { emsg3.timeEnd += Time.deltaTime; } else if (emsg3 is null) { ErrorMessage.AddMessage(msg3); } if (GameInput.GetButtonDown(GameInput.Button.Exit)) { UseableDiveHatch diveHatch = null; Collider[] hitColliders = Physics.OverlapSphere(__instance.transform.position, 3f, 1, QueryTriggerInteraction.UseGlobal); foreach (Collider hitCollider in hitColliders) { UseableDiveHatch hatch = hitCollider.gameObject.GetComponentInParent <UseableDiveHatch>(); if (hatch != null && hatch.isForWaterPark) { diveHatch = hatch; break; } } if (diveHatch != null) { diveHatch.StartCinematicMode(diveHatch.enterCinematicController, __instance); if (diveHatch.enterCustomGoalText != "" && (!diveHatch.customGoalWithLootOnly || Inventory.main.GetTotalItemCount() > 0)) { Debug.Log("OnCustomGoalEvent(" + diveHatch.enterCustomText); GoalManager.main.OnCustomGoalEvent(diveHatch.enterCustomGoalText); } if (diveHatch.secureInventory) { Inventory.Get().SecureItems(true); } } } return; } #if SN1 SubRoot currentSubRoot = __instance.GetCurrentSub(); if (currentSubRoot != null && currentSubRoot is BaseRoot && __instance.playerController.velocity.y < -20f) { RespawnPoint componentInChildren = currentSubRoot.gameObject.GetComponentInChildren <RespawnPoint>(); if (componentInChildren) { __instance.SetPosition(componentInChildren.GetSpawnPosition()); return; } } EscapePod escapePod = __instance.currentEscapePod; if (escapePod != null && __instance.playerController.velocity.y < -20f) { __instance.SetPosition(escapePod.playerSpawn.transform.position, escapePod.playerSpawn.transform.rotation); return; } #elif BZ IInteriorSpace interiorSpace = __instance.currentInterior; if (interiorSpace != null && __instance.playerController.velocity.y < -20f) { RespawnPoint respawnPoint = interiorSpace.GetRespawnPoint(); if (respawnPoint) { __instance.SetPosition(respawnPoint.GetSpawnPosition()); return; } } #endif }
// ReSharper disable once InconsistentNaming private static bool Prefix(WaterPark __instance, WaterParkCreature creature) { FishOverflowDistributor.Logger.LogTrace("WaterPark.TryBreed(WaterParkCreature) called."); //We only distribute when the WaterPark doesn't have any space left for bred creatures. //This is the only place in this method where we allow the original unpatched method to execute, //because the original method is never executed when there is no space left in the WaterPark. FishOverflowDistributor.Logger.LogTrace( $"__instance.HasFreeSpace() returns '{__instance.HasFreeSpace()}'."); if (__instance.HasFreeSpace()) { return(true); } //using Harmony's Traverse class for reflection. Harmony caches MethodInfo, FieldInfo, etc. for further use and thus increases performance. var items = Traverse .Create(__instance) .Field("items") .GetValue <List <WaterParkItem> >(); if (items == null) { FishOverflowDistributor.Logger.LogError( "FieldInfo or value for field 'items' in class 'WaterParkItem' with type 'List<WaterParkItem>' was null -> Should not happen, investigate!."); return(false); } FishOverflowDistributor.Logger.LogTrace("Checking if creature is contained in items"); //Don't know why this check is needed. Maybe TryBreed gets called on fish which arent contained in this WaterPark instance. if (!items.Contains(creature)) { return(false); } TechType creatureTechType = creature.pickupable.GetTechType(); FishOverflowDistributor.Logger.LogTrace($"Creature Tech Type = {creatureTechType.ToString()}."); FishOverflowDistributor.Logger.LogTrace( "Checking whether creatureEggs.containsKey(creatureTechType)"); //we don't want to distribute creature eggs if (WaterParkCreature.creatureEggs.ContainsKey(creatureTechType)) { return(false); } FishOverflowDistributor.Logger.LogTrace( $"Waterpark '{__instance.gameObject.name}' contains creature '{creature.gameObject.name}' and has enough space for another one."); var secondCreature = items.Find(item => item != creature && item is WaterParkCreature && // ReSharper disable once TryCastAlwaysSucceeds (item as WaterParkCreature).GetCanBreed() && item.pickupable != null && item.pickupable.GetTechType() == creatureTechType) as WaterParkCreature; if (secondCreature == null) { return(false); } FishOverflowDistributor.Logger.LogTrace( $"Waterpark contains two creatures '{creature.gameObject.name}' of TechType '{creatureTechType.ToString()}' which can breed with each other."); BaseBioReactor suitableReactor; try { //Get a reactor which has space for the item in the same base suitableReactor = SubnauticaSceneTraversalUtils .GetComponentsInSameBase <BaseBioReactor>(__instance.gameObject) .First( reactor => { var itemsContainer = Traverse .Create(reactor) .Property("container") .GetValue <ItemsContainer>(); if (itemsContainer != null) { return(itemsContainer.HasRoomFor( creature.pickupable)); } FishOverflowDistributor.Logger.LogTrace( $"PropertyInfo or value for property 'container' in class 'BaseBioReactor' with type 'ItemsContainer' was null -> Should not happen, investigate!."); return(false); }); } catch (Exception) { return(false); } if (suitableReactor == null) { FishOverflowDistributor.Logger.LogTrace("Could not find suitable reactor"); return(false); } //Reset breed time of the second creature so it can't be used to immediately breed again. secondCreature.ResetBreedTime(); FishOverflowDistributor.Logger.LogTrace( $"Found suitable reactor '{suitableReactor.gameObject.name}'."); //Now we create a pickupable from the WaterParkCreature which we can add to the reactor's inventory. //Because the creature can't be taken out from the reactor inventory, we don't need to add WaterparkCreature component //to it. This would be needed so the game knows when you drop it outside, that it came from a waterpark. GameObject newCreature = CraftData.InstantiateFromPrefab(creatureTechType, false); newCreature.SetActive(false); newCreature.transform.position = creature.transform.position + Vector3.down; var pickupable = newCreature.EnsureComponent <Pickupable>(); /*WaterParkCreatureParameters creatureParameters = * WaterParkCreature.GetParameters(creatureTechType); * * newCreature.transform.localScale = creatureParameters.initialSize * Vector3.one; * var newCreatureComponent = newCreature.AddComponent<WaterParkCreature>(); * newCreatureComponent.age = 0f; * * Traverse * .Create(newCreatureComponent) * .Field("parameters") * .SetValue(creatureParameters); * * Pickupable pickupable = creatureParameters.isPickupableOutside * ? newCreature.EnsureComponent<Pickupable>() * : newCreature.GetComponent<Pickupable>(); * * newCreature.setActive();*/ pickupable = pickupable.Pickup(false); // pickupable.GetComponent<WaterParkItem>()?.SetWaterPark(null); var itemToAdd = new InventoryItem(pickupable); var reactorItemsContainer = Traverse .Create(suitableReactor) .Property("container") .GetValue <ItemsContainer>(); if (reactorItemsContainer == null) { FishOverflowDistributor.Logger.LogError( $"PropertyInfo or value for property 'container' in class 'BaseBioReactor' with type 'ItemsContainer' was null -> Should not happen, investigate!."); return(false); } reactorItemsContainer.AddItem(pickupable); return(false); }