Ejemplo n.º 1
0
 public static void Prefix(WaterParkCreature __instance)
 {
     if (__instance.pickupable.GetTechType() == TechType.Shocker && __instance.GetCanBreed() && DayNightCycle.main.timePassed > __instance.timeNextBreed)
     {
         __instance.GetWaterPark()?.gameObject.GetComponent <PowerSource>()?.AddEnergy(100f, out _);
     }
 }
        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;
        }
Ejemplo n.º 3
0
 static void Postfix(WaterParkCreature __instance)
 {
     if (Main.config.dbgCfg.showWaterParkCreatures)
     {
         $"age: {__instance.age} canBreed: {__instance.canBreed} matureTime: {__instance.matureTime} isMature: {__instance.isMature}".
         onScreen("waterpark " + __instance.name + " " + __instance.GetHashCode());
     }
 }
Ejemplo n.º 4
0
 static void WaterParkCreature_Update_Postfix(WaterParkCreature __instance)
 {
     if (Main.config.dbgCfg.showWaterParkCreatures)
     {
         $"age: {__instance.age} canBreed: {__instance.GetCanBreed()} matureTime: {__instance.matureTime} isMature: {__instance.isMature}".
         onScreen($"waterpark {__instance.name} {__instance.GetHashCode()}");
     }
 }
        private static void StartPostfix(WaterParkCreature __instance)
        {
            if (CraftData.GetTechType(__instance.gameObject) != TechType.Rockgrub)
            {
                return;
            }

            __instance.gameObject.EnsureComponent <Pickupable>().isPickupable = true;
        }
Ejemplo n.º 6
0
        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;
                }
            }
        }
Ejemplo n.º 8
0
        public static void Prefix(WaterParkCreature __instance)
        {
            if ((__instance.GetComponent <LiveMixin>()?.IsAlive() ?? false) && Main.config.CreaturePowerGeneration.TryGetValue(__instance?.pickupable?.GetTechType() ?? TechType.None, out float powerValue))
            {
                if (!timeLastGenerated.TryGetValue(__instance, out float time))
                {
                    time = DayNightCycle.main.timePassedAsFloat;
                }

                float       power       = powerValue * (DayNightCycle.main.timePassedAsFloat - time) * Main.config.PowerGenSpeed;
                PowerSource powerSource = __instance?.GetWaterPark()?.itemsRoot?.gameObject?.GetComponent <PowerSource>();

                if (powerSource != null)
                {
                    if (!powerSource.AddEnergy(power, out float amountStored))
                    {
                        powerSource.connectedRelay?.AddEnergy(power - amountStored, out _);
                    }
                }

                timeLastGenerated[__instance] = DayNightCycle.main.timePassedAsFloat;
            }
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
        // 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);
        }
Ejemplo n.º 11
0
    // Token: 0x06000016 RID: 22 RVA: 0x00003018 File Offset: 0x00001218
    public void OnConsoleCommand_waterparkspawn(NotificationCenter.Notification n)
    {
        bool flag = !Player.main.currentWaterPark;

        if (flag)
        {
            ErrorMessage.AddDebug("Not currently inside a waterpark!");
        }
        else
        {
            bool flag2 = n != null && n.data != null && n.data.Count > 0;
            if (flag2)
            {
                string   text = (string)n.data[0];
                TechType techType;
                bool     flag3 = UWE.Utils.TryParseEnum <TechType>(text, out techType);
                if (flag3)
                {
                    bool flag4 = CraftData.IsAllowed(techType);
                    if (flag4)
                    {
                        GameObject prefabForTechType = CraftData.GetPrefabForTechType(techType, true);
                        bool       flag5             = prefabForTechType != null;
                        if (flag5)
                        {
                            bool flag6 = prefabForTechType.GetComponent <Creature>();
                            if (flag6)
                            {
                                int  num = 1;
                                int  num2;
                                bool flag7 = n.data.Count > 1 && int.TryParse((string)n.data[1], out num2);
                                if (flag7)
                                {
                                    num = num2;
                                }
                                bool flag8 = n.data.Count > 2;
                                if (flag8)
                                {
                                    float num3 = float.Parse((string)n.data[2]);
                                }
                                Debug.Log(string.Format("Spawning {0} {1}", num, techType));
                                for (int i = 0; i < num; i++)
                                {
                                    WaterParkCreature.Born(techType, Player.main.currentWaterPark, Player.main.transform.position);
                                }
                            }
                            else
                            {
                                ErrorMessage.AddDebug("Not valid creature!");
                            }
                        }
                        else
                        {
                            ErrorMessage.AddDebug("Could not find prefab for TechType = " + techType);
                        }
                    }
                }
                else
                {
                    ErrorMessage.AddDebug("Could not parse " + text + " as TechType");
                }
            }
        }
    }
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
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;
            }
        }