Exemplo n.º 1
0
        public override void receiveLeftClick(int x, int y, bool playSound = true)
        {
            if (Game1.globalFade || this.Freeze)
            {
                return;
            }

            if (this.BackButton != null && this.BackButton.containsPoint(x, y))
            {
                this.BackButton.scale = this.BackButton.baseScale;
                this.BackButtonPressed();
            }

            if (this.OkButton != null && this.OkButton.containsPoint(x, y) && this.readyToClose())
            {
                if (this.OnFarm)
                {
                    Game1.globalFadeToBlack(this.SetUpForReturnToShopMenu);
                    Game1.playSound("smallSelect");
                }
                else
                {
                    Game1.exitActiveMenu();
                    Game1.playSound("bigDeSelect");
                }
            }
            if (this.OnFarm)
            {
                Building building = Game1.getFarm().getBuildingAt(new Vector2((x + Game1.viewport.X) / Game1.tileSize, (y + Game1.viewport.Y) / Game1.tileSize));
                if (building != null && !this.NamingAnimal)
                {
                    if (building.buildingType.Contains(this.AnimalBeingPurchased.buildingTypeILiveIn.Value))
                    {
                        AnimalHouse animalHouse = (AnimalHouse)building.indoors.Value;
                        if (animalHouse.isFull())
                        {
                            Game1.showRedMessage("That Building Is Full");
                        }
                        else if (this.AnimalBeingPurchased.harvestType.Value != 2)
                        {
                            this.NamingAnimal  = true;
                            this.NewAnimalHome = building;
                            if (this.AnimalBeingPurchased.sound.Value != null && Game1.soundBank != null)
                            {
                                ICue cue = Game1.soundBank.GetCue(this.AnimalBeingPurchased.sound.Value);
                                cue.SetVariable("Pitch", 1200 + Game1.random.Next(-200, 201));
                                cue.Play();
                            }
                            this.TextBox.OnEnterPressed        += this.TextBoxEvent;
                            Game1.keyboardDispatcher.Subscriber = this.TextBox;
                            this.TextBox.Text     = this.AnimalBeingPurchased.Name;
                            this.TextBox.Selected = true;
                        }
                        else if (Game1.player.Money >= this.PriceOfAnimal)
                        {
                            this.NewAnimalHome             = building;
                            this.AnimalBeingPurchased.home = this.NewAnimalHome;
                            this.AnimalBeingPurchased.homeLocation.Value = new Vector2(this.NewAnimalHome.tileX.Value, this.NewAnimalHome.tileY.Value);
                            this.AnimalBeingPurchased.setRandomPosition(this.AnimalBeingPurchased.home.indoors.Value);
                            ((AnimalHouse)this.NewAnimalHome.indoors.Value).animals.Add(this.AnimalBeingPurchased.myID.Value, this.AnimalBeingPurchased);
                            ((AnimalHouse)this.NewAnimalHome.indoors.Value).animalsThatLiveHere.Add(this.AnimalBeingPurchased.myID.Value);
                            this.NewAnimalHome = null;
                            this.NamingAnimal  = false;
                            if (this.AnimalBeingPurchased.sound.Value != null && Game1.soundBank != null)
                            {
                                ICue cue = Game1.soundBank.GetCue(this.AnimalBeingPurchased.sound.Value);
                                cue.SetVariable("Pitch", 1200 + Game1.random.Next(-200, 201));
                                cue.Play();
                            }
                            Game1.player.Money -= this.PriceOfAnimal;
                            Game1.addHUDMessage(new HUDMessage("Purchased " + this.AnimalBeingPurchased.type.Value, Color.LimeGreen, 3500f));
                            this.AnimalBeingPurchased = new FarmAnimal(this.AnimalBeingPurchased.type.Value, this.GetNewId(), Game1.player.UniqueMultiplayerID);
                        }
                        else if (Game1.player.Money < this.PriceOfAnimal)
                        {
                            Game1.dayTimeMoneyBox.moneyShakeTimer = 1000;
                        }
                    }
                    else
                    {
                        Game1.showRedMessage(this.AnimalBeingPurchased.type.Value.Split(' ').Last() + "s Can't Live There.");
                    }
                }
                if (this.NamingAnimal && this.DoneNamingButton.containsPoint(x, y))
                {
                    this.TextBoxEnter(this.TextBox);
                    Game1.playSound("smallSelect");
                }
                else
                {
                    if (!this.NamingAnimal || !this.RandomButton.containsPoint(x, y))
                    {
                        return;
                    }
                    this.AnimalBeingPurchased.Name = Dialogue.randomName();
                    this.TextBox.Text       = this.AnimalBeingPurchased.Name;
                    this.RandomButton.scale = this.RandomButton.baseScale;
                    Game1.playSound("drumkit6");
                }
            }
            else
            {
                foreach (ClickableTextureComponent textureComponent in this.AnimalsToPurchase)
                {
                    if (textureComponent.containsPoint(x, y) && ((Object)textureComponent.item).Type == null)
                    {
                        int int32 = Convert.ToInt32(textureComponent.name);
                        if (Game1.player.Money >= int32)
                        {
                            Game1.globalFadeToBlack(this.SetUpForAnimalPlacement);
                            Game1.playSound("smallSelect");
                            this.OnFarm = true;
                            this.AnimalBeingPurchased = new FarmAnimal(textureComponent.hoverText, this.GetNewId(), Game1.player.UniqueMultiplayerID);
                            this.PriceOfAnimal        = int32;
                        }
                        else
                        {
                            Game1.addHUDMessage(new HUDMessage("Not Enough Money", Color.Red, 3500f));
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
        public static bool AddHatchedAnimal(ref AnimalHouse __instance, ref string name)
        {
            if (__instance.getBuilding() is Coop)
            {
                foreach (SObject obj in __instance.objects.Values)
                {
                    if (obj.bigCraftable.Value && obj.Name.Contains("Incubator") && (obj.heldObject.Value != null && obj.minutesUntilReady.Value <= 0) && !__instance.isFull())
                    {
                        string type = "??";
                        if (obj.heldObject.Value == null)
                        {
                            type = "White Chicken";
                        }
                        else
                        {
                            switch (obj.heldObject.Value.ParentSheetIndex)
                            {
                            case 107:
                                type = "Dinosaur";
                                break;

                            case 174:
                            case 176:
                                type = "White Chicken";
                                break;

                            case 180:
                            case 182:
                                type = "Brown Chicken";
                                break;

                            case 305:
                                type = "Void Chicken";
                                break;

                            case 442:
                                type = "Duck";
                                break;

                            default:
                                if (obj.heldObject.Value.ParentSheetIndex == Loader.DATA["Blue Chicken Egg"])
                                {
                                    type = "Blue Chicken";
                                }
                                break;
                            }
                        }

                        FarmAnimal farmAnimal = new FarmAnimal(type, Loader.HELPER.Multiplayer.GetNewID(), Game1.player.UniqueMultiplayerID);
                        while ((Game1.player.eventsSeen.Contains(3900074) || !type.Equals("Blue Chicken")) && !farmAnimal.type.Value.Equals(type))
                        {
                            farmAnimal = new FarmAnimal(type, farmAnimal.myID.Value, Game1.player.UniqueMultiplayerID);
                        }
                        farmAnimal.Name        = name;
                        farmAnimal.displayName = name;
                        Building building = __instance.getBuilding();
                        farmAnimal.home = building;
                        farmAnimal.homeLocation.Value = new Vector2(building.tileX.Value, building.tileY.Value);
                        farmAnimal.setRandomPosition(farmAnimal.home.indoors.Value);
                        (building.indoors.Value as AnimalHouse).animals.Add(farmAnimal.myID.Value, farmAnimal);
                        (building.indoors.Value as AnimalHouse).animalsThatLiveHere.Add(farmAnimal.myID.Value);
                        obj.heldObject.Value = null;
                        obj.ParentSheetIndex = 101;
                        break;
                    }
                }
            }
            else if (Game1.farmEvent != null && Game1.farmEvent is QuestionEvent)
            {
                var        qe         = Game1.farmEvent as QuestionEvent;
                FarmAnimal farmAnimal = new FarmAnimal(qe.animal.type.Value, Loader.HELPER.Multiplayer.GetNewID(), Game1.player.UniqueMultiplayerID);
                farmAnimal.Name           = name;
                farmAnimal.displayName    = name;
                farmAnimal.parentId.Value = qe.animal.myID.Value;
                Building building = __instance.getBuilding();
                farmAnimal.home = building;
                farmAnimal.homeLocation.Value = new Vector2(building.tileX.Value, building.tileY.Value);
                qe.forceProceed = true;
                farmAnimal.setRandomPosition(farmAnimal.home.indoors.Value);
                (building.indoors.Value as AnimalHouse).animals.Add(farmAnimal.myID.Value, farmAnimal);
                (building.indoors.Value as AnimalHouse).animalsThatLiveHere.Add(farmAnimal.myID.Value);
            }
            if (Game1.currentLocation.currentEvent != null)
            {
                ++Game1.currentLocation.currentEvent.CurrentCommand;
            }
            Game1.exitActiveMenu();

            return(false);
        }
Exemplo n.º 3
0
        public static void CheckEggHatched(Farmer who, AnimalHouse animalHouse)
        {
            if (who != Game1.player)
            {
                return;
            }

            foreach (StardewValley.Object @object in animalHouse.objects.Values)
            {
                if (@object.bigCraftable.Value && @object.Name.Contains("Incubator") && @object.heldObject.Value != null && @object.heldObject.Value.ParentSheetIndex == EasterEggItem.PARENT_SHEET_INDEX && @object.MinutesUntilReady <= 0 && !animalHouse.isFull())
                {
                    @object.heldObject.Value = null;
                    @object.ParentSheetIndex = 101;

                    Game1.exitActiveMenu();
                    if (animalHouse.currentEvent != null)
                    {
                        animalHouse.currentEvent.CurrentCommand = animalHouse.currentEvent.eventCommands.Length - 1;
                        animalHouse.currentEvent = new Event("none/-1000 -1000/farmer 2 9 0/pause 750/end");
                    }

                    Game1.drawDialogueNoTyping(I18N.EasterEggHatchedMessage);
                    Game1.afterDialogues = new Game1.afterFadeFunction(() => {
                        Game1.activeClickableMenu = new NamingMenu(new NamingMenu.doneNamingBehavior((string name) => {
                            AddNewHatchedRabbit(who, animalHouse, name);
                        }), Game1.content.LoadString("Strings\\StringsFromCSFiles:Event.cs.1236"), null);
                    });
                }
            }
        }
Exemplo n.º 4
0
        /*********
        ** Internal Methods
        *********/
        /// <summary>The prefix for the <see cref="AnimalHouse.resetSharedState"/> method.</summary>
        /// <param name="__instance">The current <see cref="AnimalHouse"/> instance being patched.</param>
        /// <returns><see langword="false"/>, meaning the original method will not get ran.</returns>
        /// <remarks>This reimplements the original method to add the custom incubator recipes.</remarks>
        internal static bool ResetSharedStatePrefix(AnimalHouse __instance)
        {
            __instance.resetPositionsOfAllAnimals();

            foreach (var @object in __instance.Objects.Values)
            {
                // ensure object is an incubator
                if ([email protected] || [email protected]("Incubator") || @object.heldObject.Value == null || @object.minutesUntilReady > 0)
                {
                    continue;
                }

                // ensure there is space in the animal house to hatch the animal
                if (!__instance.isFull())
                {
                    var whatHatched = "??";

                    string internalName = null;
                    if (@object.modData.TryGetValue($"{ModEntry.Instance.ModManifest.UniqueID}/recipeInternalAnimalName", out var recipeInternalAnimalNameString))
                    {
                        internalName = recipeInternalAnimalNameString;
                    }

                    if (internalName == null) // the only time the above property won't be present on an incubator is if it was populated before FAVR was installed
                    {
                        var incubatorType    = __instance.Name == "Incubator" ? IncubatorType.Regular : IncubatorType.Ostrich;
                        var incubatorRecipes = ModEntry.Instance.CustomIncubatorRecipes.Where(incubatorRecipe => incubatorRecipe.IncubatorType.HasFlag(incubatorType)).ToList();

                        // try to find the recipe that has the corresponding item
                        var recipes = incubatorRecipes.Where(IncubatorRecipe => IncubatorRecipe.InputId == @object.heldObject.Value.ParentSheetIndex);
                        if (recipes.Any())
                        {
                            var totalChance  = recipes.Select(recipe => recipe.Chance).Sum();
                            var randomChance = (float)(Game1.random.NextDouble() * totalChance);
                            foreach (var recipe in recipes)
                            {
                                randomChance -= recipe.Chance;
                                if (randomChance <= 0)
                                {
                                    internalName = recipe.InternalAnimalName;
                                    break;
                                }
                            }
                        }
                    }

                    var animalName = ModEntry.Instance.Api.GetAnimalByInternalName(internalName)?.Name
                                     ?? ModEntry.Instance.Api.GetAnimalSubtypeByInternalName(internalName)?.Name;

                    if (animalName != null)
                    {
                        whatHatched = $"A new baby {animalName.ToLower()} hatched!";
                    }

                    if (whatHatched == "??")
                    {
                        // if there was no valid recipe, then just remove the object from the incubator (this is the case when the player puts an egg in the incubator then removes the mod that adds that recipe)
                        @object.heldObject.Value = null;
                        return(false);
                    }

                    // run hatched event
                    __instance.currentEvent = new Event($"none/-1000 -1000/farmer 2 9 0/pause 250/message \"{whatHatched}\"/pause 500/animalNaming/pause 500/end");
                    break;
                }

                // tell player building is full if they haven't already been told
                if (!__instance.hasShownIncubatorBuildingFullMessage)
                {
                    __instance.hasShownIncubatorBuildingFullMessage = true;
                    Game1.showGlobalMessage(Game1.content.LoadString("Strings\\Locations:AnimalHouse_Incubator_HouseFull"));
                }
            }

            // call the base resetSharedState method
            // this approach isn't ideal but when using regular reflection and invoking the MethodInfo directly, it would call this patch (instead of the base method) resulting in a stack overflow
            // https://stackoverflow.com/questions/4357729/use-reflection-to-invoke-an-overridden-base-method/14415506#14415506
            var baseMethod      = typeof(GameLocation).GetMethod("resetSharedState", BindingFlags.NonPublic | BindingFlags.Instance);
            var functionPointer = baseMethod.MethodHandle.GetFunctionPointer();
            var function        = (System.Action)Activator.CreateInstance(typeof(System.Action), __instance, functionPointer);

            function.Invoke();
            return(false);
        }
Exemplo n.º 5
0
        /// <summary>The prefix for the <see cref="AnimalHouse.addNewHatchedAnimal"/> method.</summary>
        /// <param name="name">The name of the animal.</param>
        /// <param name="__instance">The current <see cref="AnimalHouse"/> instance being patched.</param>
        /// <returns><see langword="false"/>, meaning the original method will not get ran.</returns>
        /// <remarks>This reimplements the original method to add the custom incubator recipes.</remarks>
        internal static bool AddNewHatchedAnimalPrefix(string name, AnimalHouse __instance)
        {
            var foundIncubator = false;

            foreach (var @object in __instance.Objects.Values)
            {
                // ensure object is an incubator
                if ([email protected] || [email protected]("Incubator") || @object.heldObject.Value == null || @object.minutesUntilReady > 0 || __instance.isFull())
                {
                    continue;
                }

                // get the animal to spawn
                string internalName = null;
                if (@object.modData.TryGetValue($"{ModEntry.Instance.ModManifest.UniqueID}/recipeInternalAnimalName", out var recipeInternalAnimalNameString))
                {
                    internalName = recipeInternalAnimalNameString;
                    @object.modData.Remove($"{ModEntry.Instance.ModManifest.UniqueID}/recipeInternalAnimalName");
                }

                if (internalName == null) // the only time the above property won't be present on an incubator is if it was populated before FAVR was installed
                {
                    var incubatorType    = __instance.Name == "Incubator" ? IncubatorType.Regular : IncubatorType.Ostrich;
                    var incubatorRecipes = ModEntry.Instance.CustomIncubatorRecipes.Where(incubatorRecipe => incubatorRecipe.IncubatorType.HasFlag(incubatorType)).ToList();

                    // try to find the recipe that has the corresponding item
                    var recipes = incubatorRecipes.Where(IncubatorRecipe => IncubatorRecipe.InputId == @object.heldObject.Value.ParentSheetIndex);
                    if (!recipes.Any())
                    {
                        ModEntry.Instance.Monitor.Log($"Couldn't find a recipe for the {@object.Name} that has an input id item of {@object.heldObject.Value.ParentSheetIndex}, emptying incubator");
                        ClearIncubator(@object);
                        continue;
                    }

                    var totalChance  = recipes.Select(recipe => recipe.Chance).Sum();
                    var randomChance = (float)(Game1.random.NextDouble() * totalChance);
                    foreach (var recipe in recipes)
                    {
                        randomChance -= recipe.Chance;
                        if (randomChance <= 0)
                        {
                            internalName = recipe.InternalAnimalName;
                            break;
                        }
                    }
                }

                // ensure animal exists
                var isSubtype = false;
                var animal    = ModEntry.Instance.Api.GetAnimalByInternalName(internalName);
                if (animal == null)
                {
                    isSubtype = true;
                    animal    = ModEntry.Instance.Api.GetAnimalByInternalSubtypeName(internalName);
                }
                if (animal == null)
                {
                    ModEntry.Instance.Monitor.Log($"Couldn't find an animal or animal type with the name of {internalName}, emptying incubator");
                    ClearIncubator(@object);
                    continue;
                }

                // pick a random animal subtype that is valid and should be dropped from the recipe
                if (!isSubtype)
                {
                    var validSubtypes = animal.Subtypes.Where(subtype => subtype.IsIncubatable);
                    if (validSubtypes.Count() == 0) // ensure there was atleast one incububatable subtype, otherwise, just drop any subtype
                    {
                        validSubtypes = animal.Subtypes;
                    }

                    internalName = validSubtypes.ElementAt(Game1.random.Next(validSubtypes.Count())).InternalName;
                }

                var farmAnimal = CreateAnimal(name, internalName, __instance);

                ClearIncubator(@object);

                foundIncubator = true;
                break;
            }

            // if no incubator could be found, then create the animal based on the event instead (I *think* this means the animal wasn't created in an incubator, but was born by another animal (need to check to make sure))
            if (!foundIncubator && Game1.farmEvent != null && Game1.farmEvent is QuestionEvent questionEvent)
            {
                var farmAnimal = CreateAnimal(name, questionEvent.animal.type.Value, __instance);
                farmAnimal.parentId.Value  = questionEvent.animal.myID;
                questionEvent.forceProceed = true;
            }

            Game1.exitActiveMenu();
            return(false);
        }
Exemplo n.º 6
0
        public static void NewHatchedAnimalPrefix(AnimalHouse __instance, ref string name, ref string __state)
        {
            if (__instance.getBuilding() is Coop)
            {
                foreach (StardewValley.Object @object in __instance.objects.Values)
                {
                    if ((bool)((NetFieldBase <bool, NetBool>)@object.bigCraftable) && @object.Name.Contains("Incubator") && (@object.heldObject.Value != null && (int)((NetFieldBase <int, NetIntDelta>)@object.minutesUntilReady) <= 0) && !__instance.isFull())
                    {
                        FarmAnimal farmAnimal = ModEntry.BirthAnimal(__instance, @object.heldObject.Value.ParentSheetIndex);

                        if (farmAnimal != null)
                        {
                            farmAnimal.Name          = name;
                            farmAnimal.displayName   = name;
                            @object.heldObject.Value = (StardewValley.Object)null;
                            @object.ParentSheetIndex = 101;
                            __state = farmAnimal.type;
                        }
                        break;
                    }
                }
            }
        }
Exemplo n.º 7
0
        public static void ResetSharedStatePrefix(AnimalHouse __instance, Event __state)
        {
            foreach (StardewValley.Object @object in __instance.objects.Values)
            {
                if ((bool)((NetFieldBase <bool, NetBool>)@object.bigCraftable) && @object.Name.Contains("Incubator") && (@object.heldObject.Value != null && (int)((NetFieldBase <int, NetIntDelta>)@object.minutesUntilReady) <= 0) && !__instance.isFull())
                {
                    string str   = "??";
                    int    eggID = @object.heldObject.Value.ParentSheetIndex;
                    if (ModEntry.IsCustomEgg(eggID))
                    {
                        if (ModEntry.modEntry.modData.customEggsAndHatchedAnimals.ContainsKey(eggID))
                        {
                            string animalType = ModEntry.modEntry.modData.customEggsAndHatchedAnimals[eggID][modDataBreedIndex];
                            if (animalType.Contains("Void"))
                            {
                                str = Game1.content.LoadString("Strings\\Locations:AnimalHouse_Incubator_Hatch_VoidEgg");
                            }
                            else if (animalType.Contains("Dinosaur"))
                            {
                                str = Game1.content.LoadString("Strings\\Locations:AnimalHouse_Incubator_Hatch_DinosaurEgg");
                            }
                            else if (animalType.Contains("Duck"))
                            {
                                str = Game1.content.LoadString("Strings\\Locations:AnimalHouse_Incubator_Hatch_DuckEgg");
                            }
                            else
                            {
                                str = Game1.content.LoadString("Strings\\Locations:AnimalHouse_Incubator_Hatch_RegularEgg");
                            }
                        }
                        else
                        {
                            str = Game1.content.LoadString("Strings\\Locations:AnimalHouse_Incubator_Hatch_RegularEgg");
                        }

                        if (str != "??")
                        {
                            modEntry.eventText = str;
                            break;
                        }
                    }
                }
            }
        }