Пример #1
0
        public static void CollectFish(Farmer who, FishingRod rod)
        {
            IReflectedField <int> recastTimerMs = Reflection.GetField <int>(rod, "recastTimerMs");

            int whichFish   = Reflection.GetField <int>(rod, "whichFish").GetValue();
            int fishQuality = Reflection.GetField <int>(rod, "fishQuality").GetValue();

            string itemCategory = Reflection.GetField <string>(rod, "itemCategory").GetValue();

            if (!Game1.isFestival())
            {
                who.faceDirection(2);
                who.FarmerSprite.setCurrentFrame(84);
            }

            if (Game1.random.NextDouble() < 0.025)
            {
                who.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite("LooseSprites\\Cursors",
                                                                                     new Rectangle(653, 858, 1, 1), 9999f, 1, 1,
                                                                                     who.Position + new Vector2(Game1.random.Next(-3, 2) * 4, -32f), false, false,
                                                                                     (float)(who.getStandingY() / 10000.0 + 1.0 / 500.0), 0.04f, Color.LightBlue, 5f, 0.0f,
                                                                                     0.0f, 0.0f)
                {
                    acceleration = new Vector2(0.0f, 0.25f)
                });
            }

            if (!who.IsLocalPlayer)
            {
                return;
            }

            who.currentLocation.localSound("coin");
            if (!rod.treasureCaught)
            {
                recastTimerMs.SetValue(200);
                Object @object = null;
                switch (itemCategory)
                {
                case "Object":
                {
                    @object = new Object(whichFish, 1, false, -1, fishQuality);
                    if (whichFish == GameLocation.CAROLINES_NECKLACE_ITEM)
                    {
                        @object.questItem.Value = true;
                    }

                    if (whichFish == 79 || whichFish == 842)
                    {
                        @object = who.currentLocation.tryToCreateUnseenSecretNote(who);
                        if (@object == null)
                        {
                            return;
                        }
                    }

                    if (rod.caughtDoubleFish)
                    {
                        @object.Stack = 2;
                    }

                    break;
                }

                case "Furniture":
                {
                    @object = new Furniture(whichFish, Vector2.Zero);
                    break;
                }
                }
                bool fromFishPond = rod.fromFishPond;
                who.completelyStopAnimatingOrDoingAction();
                rod.doneFishing(who, !fromFishPond);
                if (!Game1.isFestival() && !fromFishPond && (itemCategory == "Object" && Game1.player.team.specialOrders != null))
                {
                    foreach (SpecialOrder specialOrder in Game1.player.team.specialOrders)
                    {
                        specialOrder.onFishCaught?.Invoke(Game1.player, @object);
                    }
                }

                if (Game1.isFestival() || who.addItemToInventoryBool(@object))
                {
                    return;
                }

                Game1.activeClickableMenu = new ItemGrabMenu(new List <Item>
                {
                    @object
                }, rod).setEssential(true);
            }
            else
            {
                rod.fishCaught      = false;
                rod.showingTreasure = true;
                who.UsingTool       = true;
                int initialStack = 1;
                if (rod.caughtDoubleFish)
                {
                    initialStack = 2;
                }

                Object @object = new Object(whichFish, initialStack, false, -1, fishQuality);
                if (Game1.player.team.specialOrders != null)
                {
                    foreach (SpecialOrder specialOrder in Game1.player.team.specialOrders)
                    {
                        specialOrder.onFishCaught?.Invoke(Game1.player, @object);
                    }
                }
                bool inventoryBool = who.addItemToInventoryBool(@object);
                rod.animations.Add(new TemporaryAnimatedSprite("LooseSprites\\Cursors", new Rectangle(64, 1920, 32, 32), 500f, 1, 0, who.Position + new Vector2(-32f, -160f), false, false, (float)(who.getStandingY() / 10000.0 + 1.0 / 1000.0), 0.0f, Color.White, 4f, 0.0f, 0.0f, 0.0f)
                {
                    motion                  = new Vector2(0.0f, -0.128f),
                    timeBasedMotion         = true,
                    endFunction             = rod.openChestEndFunction,
                    extraInfoForEndBehavior = inventoryBool ? 0 : 1,
                    alpha     = 0.0f,
                    alphaFade = -1f / 500f
                });
            }
        }
Пример #2
0
        private void OpenTreasureEndFunction(FishingRod rod, Farmer user, int includeFish)
        {
            ModFishing.Instance.Monitor.Log("Successfully replaced treasure", LogLevel.Trace);

            ConfigMain.ConfigGlobalTreasure config = ModFishing.Instance.MainConfig.GlobalTreasureSettings;
            int clearWaterDistance = ModFishing.Instance.Helper.Reflection.GetField <int>(rod, "clearWaterDistance")?.GetValue() ?? 5;

            int whichFish   = ModFishing.Instance.Helper.Reflection.GetField <int>(rod, "whichFish").GetValue();
            int fishQuality = ModFishing.Instance.Helper.Reflection.GetField <int>(rod, "fishQuality").GetValue();

            // Gain experience and call vanilla code for this
            user.gainExperience(5, 10 * (clearWaterDistance + 1));
            rod.doneFishing(user, true);
            user.completelyStopAnimatingOrDoingAction();

            // REWARDS
            List <Item> rewards = new List <Item>();

            if (includeFish == 1)
            {
                rewards.Add(new SObject(whichFish, 1, false, -1, fishQuality));
            }

            List <ITreasureData> possibleLoot = new List <ITreasureData>(ModFishing.Instance.TreasureConfig.PossibleLoot)
                                                .Where(treasure => treasure.IsValid(user)).ToList();

            // Select rewards
            float chance = 1f;
            int   streak = ModFishing.Instance.Api.GetStreak(user);

            while (possibleLoot.Count > 0 && rewards.Count < config.MaxTreasureQuantity && Game1.random.NextDouble() <= chance)
            {
                ITreasureData treasure = possibleLoot.Choose(Game1.random);

                // Choose an ID for the treasure
                IList <int> ids = treasure.PossibleIds();
                int         id  = ids[Game1.random.Next(ids.Count)];

                // Lost books have custom handling
                if (id == Objects.LostBook)
                {
                    if (user.archaeologyFound == null || !user.archaeologyFound.ContainsKey(102) || user.archaeologyFound[102][0] >= 21)
                    {
                        possibleLoot.Remove(treasure);
                        continue;
                    }
                    Game1.showGlobalMessage("You found a lost book. The library has been expanded.");
                }

                // Create reward item
                Item reward;
                if (treasure.MeleeWeapon)
                {
                    reward = new MeleeWeapon(id);
                }
                else if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange)
                {
                    reward = new Ring(id);
                }
                else if (id >= 504 && id <= 513)
                {
                    reward = new Boots(id);
                }
                else
                {
                    // Random quantity
                    int count = Game1.random.Next(treasure.MinAmount, treasure.MaxAmount);

                    reward = new SObject(Vector2.Zero, id, count);
                }

                // Add the reward
                rewards.Add(reward);

                // Check if this reward shouldn't be duplicated
                if (!config.AllowDuplicateLoot || !treasure.AllowDuplicates)
                {
                    possibleLoot.Remove(treasure);
                }

                // Update chance
                chance *= config.AdditionalLootChance + streak * config.StreakAdditionalLootChance;
            }

            // Add bait if no rewards were selected. NOTE: This should never happen
            if (rewards.Count == 0)
            {
                ModFishing.Instance.Monitor.Log("Could not find any valid loot for the treasure chest. Check your treasure.json?", LogLevel.Warn);
                rewards.Add(new SObject(685, Game1.random.Next(2, 5) * 5));
            }

            // Show rewards GUI
            ModFishing.Instance.Monitor.Log($"Treasure rewards: {string.Join(", ", rewards)}", LogLevel.Trace);
            Game1.activeClickableMenu = new ItemGrabMenu(rewards);
            ((ItemGrabMenu)Game1.activeClickableMenu).source = 3;
            user.completelyStopAnimatingOrDoingAction();
        }
Пример #3
0
        public static void OpenTreasureMenuEndFunction(FishingRod rod, int extra)
        {
            ModFishing.INSTANCE.Monitor.Log("Successfully replaced treasure", LogLevel.Trace);

            ConfigMain config             = ModFishing.INSTANCE.Config;
            SFarmer    lastUser           = ModFishing.INSTANCE.Helper.Reflection.GetPrivateValue <SFarmer>(rod, "lastUser");
            int        clearWaterDistance = 5;

            if (config.OverrideFishing)
            {
                if (FishingRodOverrides.ClearWaterDistances.ContainsKey(lastUser))
                {
                    clearWaterDistance = FishingRodOverrides.ClearWaterDistances[lastUser];
                }
                else
                {
                    ModFishing.INSTANCE.Monitor.Log("The bobber bar was not replaced. Fishing might not be overridden by this mod", LogLevel.Warn);
                }
            }
            int whichFish   = ModFishing.INSTANCE.Helper.Reflection.GetPrivateValue <int>(rod, "whichFish");
            int fishQuality = ModFishing.INSTANCE.Helper.Reflection.GetPrivateValue <int>(rod, "fishQuality");

            lastUser.gainExperience(5, 10 * (clearWaterDistance + 1));
            rod.doneFishing(lastUser, true);
            lastUser.completelyStopAnimatingOrDoingAction();

            // REWARDS
            List <Item> rewards = new List <Item>();

            if (extra == 1)
            {
                rewards.Add(new StardewValley.Object(whichFish, 1, false, -1, fishQuality));
            }

            List <TreasureData> possibleLoot = new List <TreasureData>(config.PossibleLoot)
                                               .Where(treasure => treasure.IsValid(lastUser.FishingLevel, clearWaterDistance)).ToList();

            // Select rewards
            float chance = 1f;
            int   streak = FishHelper.GetStreak(lastUser);

            while (possibleLoot.Count > 0 && rewards.Count < config.MaxTreasureQuantity && Game1.random.NextDouble() <= chance)
            {
                TreasureData treasure = possibleLoot.Choose(Game1.random);

                int id = treasure.id + Game1.random.Next(treasure.idRange - 1);

                if (id == Objects.LOST_BOOK)
                {
                    if (lastUser.archaeologyFound == null || !lastUser.archaeologyFound.ContainsKey(102) || lastUser.archaeologyFound[102][0] >= 21)
                    {
                        continue;
                    }
                    Game1.showGlobalMessage("You found a lost book. The library has been expanded.");
                }

                int count = Game1.random.Next(treasure.minAmount, treasure.maxAmount);

                Item reward;
                if (treasure.meleeWeapon)
                {
                    reward = new MeleeWeapon(id);
                }
                else if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange)
                {
                    reward = new Ring(id);
                }
                else if (id >= 504 && id <= 513)
                {
                    reward = new Boots(id);
                }
                else
                {
                    reward = new StardewValley.Object(Vector2.Zero, id, count);
                }

                rewards.Add(reward);
                if (!config.AllowDuplicateLoot || !treasure.allowDuplicates)
                {
                    possibleLoot.Remove(treasure);
                }

                //rewards.Add(new StardewValley.Object(Vector2.Zero, Objects.BAIT, Game1.random.Next(10, 25)));
            }

            // Add bait if no rewards were selected. NOTE: This should never happen
            if (rewards.Count == 0)
            {
                ModFishing.INSTANCE.Monitor.Log("Could not find any valid loot for the treasure chest. Check your treasure.json?", LogLevel.Warn);
                rewards.Add(new StardewValley.Object(685, Game1.random.Next(2, 5) * 5, false, -1, 0));
            }

            // Show rewards GUI
            Game1.activeClickableMenu = new ItemGrabMenu(rewards);
            (Game1.activeClickableMenu as ItemGrabMenu).source = 3;
            lastUser.completelyStopAnimatingOrDoingAction();
        }