public static Optional <ItemsContainer> GetBasedOnOwnersType(GameObject owner)
        {
            SeamothStorageContainer seamothStorageContainer = owner.GetComponent <SeamothStorageContainer>();

            if (seamothStorageContainer != null)
            {
                return(Optional.Of(seamothStorageContainer.container));
            }
            StorageContainer storageContainer = owner.GetComponentInChildren <StorageContainer>();

            if (storageContainer != null)
            {
                return(Optional.Of(storageContainer.container));
            }
            BaseBioReactor baseBioReactor = owner.GetComponentInChildren <BaseBioReactor>();

            if (baseBioReactor != null)
            {
                ItemsContainer container = (ItemsContainer)baseBioReactor.ReflectionGetProperty("container");
                return(Optional.Of(container));
            }
            if (owner.name == "Player")
            {
                return(Optional.Of(Inventory.Get().container));
            }

            Log.Debug("Couldn't resolve container from gameObject: " + owner.name);

            return(Optional.Empty);
        }
예제 #2
0
        protected float GetBioreactorAvailableCharge(BaseBioReactor reactor)
        {
            if (BaseBioreactor_charge == null)
            {
                BaseBioreactor_charge = typeof(BaseBioReactor).GetField("charge", BindingFlags.NonPublic | BindingFlags.Static);
            }

            Dictionary <TechType, float> chargeValues = (Dictionary <TechType, float>)BaseBioreactor_charge.GetValue(null);
            ItemsContainer items = GetBioreactorItems(reactor);

            float sum = 0;

            foreach (InventoryItem inventoryItem in items)
            {
                Pickupable item            = inventoryItem.item;
                TechType   techType        = item.GetTechType();
                float      itemChargeValue = 0;
                if (chargeValues.TryGetValue(techType, out itemChargeValue))
                {
                    sum += itemChargeValue;
                }
            }

            return(sum - reactor._toConsume);
        }
예제 #3
0
        internal static bool Prefix(BaseBioReactor __instance, ProtobufSerializer serializer)
        {
            QuickLogger.Debug("OnProtoDeserializeObjectTree");

            CyBioReactorMini.GetMiniReactor(__instance).OnProtoDeserializeObjectTree(serializer);
            return(false);
        }
예제 #4
0
        public CyBioReactorMini(BaseBioReactor bioReactor)
        {
            BioReactor = bioReactor;

            string id = BioReactor.GetComponentInParent <PrefabIdentifier>().Id;

            SaveData = new CyBioReactorSaveData(id);
        }
예제 #5
0
        protected ItemsContainer GetBioreactorItems(BaseBioReactor reactor)
        {
            if (BaseBioreactor_get_container == null)
            {
                BaseBioreactor_get_container = typeof(BaseBioReactor).GetMethod("get_container", BindingFlags.NonPublic | BindingFlags.Instance);
            }

            return((ItemsContainer)BaseBioreactor_get_container.Invoke(reactor, new object[] { }));
        }
        public CyBioReactorMini(ref BaseBioReactor bioReactor)
        {
            BioReactor = bioReactor;

            PrefabIdentifier prefabIdentifier = bioReactor.GetComponentInParent <PrefabIdentifier>() ?? bioReactor.GetComponent <PrefabIdentifier>();

            string id = prefabIdentifier.Id;

            QuickLogger.Debug($"CyBioReactorMini PrefabIdentifier: {id}");

            SaveData = new CyBioReactorSaveData(id);
        }
        internal static CyBioReactorMini GetMiniReactor(ref BaseBioReactor bioReactor)
        {
            if (LookupMiniReactor.TryGetValue(bioReactor, out CyBioReactorMini existingBioMini))
            {
                return(existingBioMini);
            }

            var createdBioMini = new CyBioReactorMini(ref bioReactor);

            LookupMiniReactor.Add(bioReactor, createdBioMini);

            QuickLogger.Debug("CyBioReactorMini Connected");

            return(createdBioMini);
        }
        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;
                }
            }
        }
예제 #9
0
        public static Optional <ItemsContainer> TryGetContainerByOwner(GameObject owner)
        {
            SeamothStorageContainer seamothStorageContainer = owner.GetComponent <SeamothStorageContainer>();

            if (seamothStorageContainer)
            {
                return(Optional.Of(seamothStorageContainer.container));
            }
            StorageContainer storageContainer = owner.GetComponentInChildren <StorageContainer>();

            if (storageContainer)
            {
                return(Optional.Of(storageContainer.container));
            }
            BaseBioReactor baseBioReactor = owner.GetComponentInChildren <BaseBioReactor>();

            if (baseBioReactor)
            {
                ItemsContainer container = (ItemsContainer)baseBioReactor.ReflectionGetProperty("container");
                return(Optional.Of(container));
            }
            if (owner.name == "Player")
            {
                return(Optional.Of(Inventory.Get().container));
            }
            if (owner.GetComponentInChildren <PingInstance>().GetLabel().StartsWith("Player "))
            {
                if (playerManager == null)
                {
                    playerManager = NitroxServiceLocator.LocateService <PlayerManager>();
                }

                Optional <RemotePlayer> opPlayer = playerManager.FindByName(owner.name);
                if (opPlayer.HasValue)
                {
                    return(Optional.Of(opPlayer.Value.Inventory));
                }
            }

            Log.Debug("Couldn't resolve container from gameObject: " + owner.name);

            return(Optional.Empty);
        }
예제 #10
0
        internal static bool Prefix(BaseBioReactor __instance, float requested, ref float __result)
        {
            __result = CyBioReactorMini.GetMiniReactor(__instance).ProducePower(requested);

            return(false); // Full override
        }
예제 #11
0
 internal static void Postfix(BaseBioReactor __instance)
 {
     CyBioReactorMini.GetMiniReactor(__instance).UpdateDisplayText();
 }
예제 #12
0
        internal static bool Prefix(BaseBioReactor __instance, ref BaseBioReactorGeometry model)
        {
            CyBioReactorMini.GetMiniReactor(__instance).OnPdaOpen(model);

            return(false); // Full override
        }
예제 #13
0
        public static IEnumerator AddToReactor(SubRoot subRoot, TechType fishType, Vector2int sizePerFish, BaseBioReactor reactor)
        {
            var task = CraftData.GetPrefabForTechTypeAsync(fishType, false);

            yield return(task);

            var prefab = task.GetResult();

            prefab.SetActive(false);

            if (!reactor.container.HasRoomFor(sizePerFish.x, sizePerFish.y))
            {
                var breedCount = 1;

                if (QModServices.Main.ModPresent("FCSEnergySolutions"))
                {
                    AGCompat.TryOverflowIntoAlterraGens(subRoot, fishType, ref breedCount);
                }

                if (QModServices.Main.ModPresent("CyclopsBioReactor") && breedCount > 0)
                {
                    CBRCompat.TryOverflowIntoCyclopsBioreactors(subRoot, fishType, ref breedCount);
                }

                if (breedCount > 0)
                {
                    TryOverflowIntoBioreactors(subRoot, fishType, ref breedCount);
                }

                yield break;
            }

            var gameObject = Object.Instantiate(prefab);

            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
            reactor.container.AddItem(pickupable);
        }
 internal static void Postfix(BaseBioReactor __instance)
 {
     CyBioReactorMini.GetMiniReactor(ref __instance).Start();
 }
예제 #15
0
 internal BioEnergy(Pickupable pickupable, float energy)
 {
     Pickupable      = pickupable;
     RemainingEnergy = energy;
     MaxEnergy       = BaseBioReactor.GetCharge(pickupable.GetTechType());
 }
예제 #16
0
        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;
            }
        }
예제 #17
0
 internal static void Postfix(BaseBioReactor __instance, ProtobufSerializer serializer)
 {
     QuickLogger.Debug("OnProtoSerializeObjectTree");
     CyBioReactorMini.GetMiniReactor(__instance).OnProtoSerializeObjectTree(serializer);
 }
예제 #18
0
 internal static void Prefix(BaseBioReactor __instance)
 {
     powerLevel = __instance._powerSource.power;
 }
        private static void Postfix(Aquarium aquarium, AquariumInfo __result)
        {
            //Check for valid AquariumInfo as well as make sure the aquarium is full.
            if (__result == null || aquarium.storageContainer.container.HasRoomFor(1, 1))
            {
                return;
            }

            SubRoot subRoot = aquarium.GetComponentInParent <SubRoot>();

            //Ensure the aquarium is built in or on a Cyclops a Base.
            if (subRoot == null)
            {
                return;
            }

            double timePassed             = DayNightCycle.main.timePassed;
            bool   bioReactorsFull        = false;
            bool   cyclopsBioReactorsFull = !QModServices.Main.ModPresent("CyclopsBioReactor");
            bool   alterraGensFull        = !QModServices.Main.ModPresent("FCSEnergySolutions");

            //Checks all types of fish in the aquarium and collects data on how many to be put in the BioReactors
            for (int i = 0; i < __result.BreedInfo.Count; i++)
            {
                //Full stop if all reactors are full.
                if (alterraGensFull && cyclopsBioReactorsFull && bioReactorsFull)
                {
                    break;
                }

                AquariumInfo.AquariumBreedTime nextBreed = __result.BreedInfo[i];

                //skip if not breeding time yet.
                if (nextBreed.BreedTime > timePassed)
                {
                    continue;
                }

                TechType fishType = nextBreed.FishType;

                //Check if fish can go in bioreactors
                if (BaseBioReactor.GetCharge(fishType) <= 0)
                {
                    continue;
                }

                int breedCount = nextBreed.BreedCount;

                if (!alterraGensFull && breedCount > 0)
                {
                    alterraGensFull = AGCompat.TryOverflowIntoAlterraGens(subRoot, fishType, ref breedCount);
                }

                if (!cyclopsBioReactorsFull && breedCount > 0)
                {
                    cyclopsBioReactorsFull = CBRCompat.TryOverflowIntoCyclopsBioreactors(subRoot, fishType, ref breedCount);
                }

                if (!bioReactorsFull && breedCount > 0)
                {
                    bioReactorsFull = Main.TryOverflowIntoBioreactors(subRoot, fishType, ref breedCount);
                }

                nextBreed.BreedTime += 600.0;
                AquariumInfo.Update(aquarium);
            }
        }
예제 #20
0
        internal static void Postfix(BaseBioReactor __instance)
        {
            float powerDelta = __instance._powerSource.power - powerLevel;

            __instance._powerSource.SetPower(powerLevel + powerDelta * powerModifier);
        }
예제 #21
0
 internal static void Postfix(BaseBioReactor __instance)
 {
     __instance._powerSource.maxPower = Mathf.Max(maxPower, 0);
 }
예제 #22
0
        internal static bool Prefix(BaseBioReactor __instance)
        {
            CyBioReactorMini.GetMiniReactor(__instance).OnHover();

            return(false); // Full override
        }
예제 #23
0
        private static void Postfix(BaseBioReactor __instance)
        {
            ItemsContainer container = (ItemsContainer)BaseBioReactor_container.GetValue(__instance);

            container.Resize(Main.config.BioreactorWidth, Main.config.BioreactorHeight);
        }
예제 #24
0
 public BioreactorPowerSourceInfo(PowerSource source) : base(source, TechType.BaseBioReactor)
 {
     reactor = source.GetComponent <BaseBioReactor>();
 }