예제 #1
0
        private void UpdateTick(object sender, UpdateTickedEventArgs e)
        {
            if (Game1.player == null)
            {
                return;
            }

            if (Game1.player.CurrentTool is FishingRod)
            {
                FishingRod currentTool = Game1.player.CurrentTool as FishingRod;
                if (Config.fastBite && currentTool.timeUntilFishingBite > 0)
                {
                    currentTool.timeUntilFishingBite /= 2; // 快速咬钩
                }
                if (Config.autoHit && currentTool.isNibbling && !currentTool.isReeling && !currentTool.hit && !currentTool.pullingOutOfWater && !currentTool.fishCaught)
                {
                    currentTool.DoFunction(Game1.player.currentLocation, 1, 1, 1, Game1.player); // 自动咬钩
                }
                if (Config.maxCastPower)
                {
                    currentTool.castingPower = 1;
                }
            }

            if (Game1.activeClickableMenu is BobberBar) // 自动小游戏
            {
                BobberBar bar                  = Game1.activeClickableMenu as BobberBar;
                float     barPos               = Helper.Reflection.GetField <float>(bar, "bobberBarPos").GetValue();
                float     barHeight            = Helper.Reflection.GetField <int>(bar, "bobberBarHeight").GetValue();
                float     fishPos              = Helper.Reflection.GetField <float>(bar, "bobberPosition").GetValue();
                float     treasurePos          = Helper.Reflection.GetField <float>(bar, "treasurePosition").GetValue();
                float     distanceFromCatching = Helper.Reflection.GetField <float>(bar, "distanceFromCatching").GetValue();

                bool  treasureCaught = Helper.Reflection.GetField <bool>(bar, "treasureCaught").GetValue();
                bool  hasTreasure    = Helper.Reflection.GetField <bool>(bar, "treasure").GetValue();
                float treasureScale  = Helper.Reflection.GetField <float>(bar, "treasureScale").GetValue();
                float bobberBarSpeed = Helper.Reflection.GetField <float>(bar, "bobberBarSpeed").GetValue();
                float barPosMax      = 568 - barHeight;

                float min = barPos + barHeight / 4,
                      max = barPos + barHeight / 1.5f;

                if (Config.catchTreasure && hasTreasure && !treasureCaught && (distanceFromCatching > 0.75 || catching))
                {
                    catching = true;
                    fishPos  = treasurePos;
                }
                if (catching && distanceFromCatching < 0.15)
                {
                    catching = false;
                    fishPos  = Helper.Reflection.GetField <float>(bar, "bobberPosition").GetValue();
                }

                if (fishPos < min)
                {
                    bobberBarSpeed -= 0.35f + (min - fishPos) / 20;
                    Helper.Reflection.GetField <float>(bar, "bobberBarSpeed").SetValue(bobberBarSpeed);
                }
                else if (fishPos > max)
                {
                    bobberBarSpeed += 0.35f + (fishPos - max) / 20;
                    Helper.Reflection.GetField <float>(bar, "bobberBarSpeed").SetValue(bobberBarSpeed);
                }
                else
                {
                    float target = 0.1f;
                    if (bobberBarSpeed > target)
                    {
                        bobberBarSpeed -= 0.1f + (bobberBarSpeed - target) / 25;
                        if (barPos + bobberBarSpeed > barPosMax)
                        {
                            bobberBarSpeed /= 2; // 减小触底反弹
                        }
                        if (bobberBarSpeed < target)
                        {
                            bobberBarSpeed = target;
                        }
                    }
                    else
                    {
                        bobberBarSpeed += 0.1f + (target - bobberBarSpeed) / 25;
                        if (barPos + bobberBarSpeed < 0)
                        {
                            bobberBarSpeed /= 2; // 减小触顶反弹
                        }
                        if (bobberBarSpeed > target)
                        {
                            bobberBarSpeed = target;
                        }
                    }
                    Helper.Reflection.GetField <float>(bar, "bobberBarSpeed").SetValue(bobberBarSpeed);
                }
            }
            else
            {
                catching = false;
            }
        }
예제 #2
0
        /// <summary>
        /// Update mod state.  Try to keep processing quick here.
        /// </summary>
        public void OnUpdate()
        {
            if (!(Game1.player.CurrentTool is FishingRod))
            {
                return;
            }

            FishingRod currentTool = Game1.player.CurrentTool as FishingRod;

            // Could set up a state machine to track this, but for now just check either in the minigame or not.
            if (Game1.activeClickableMenu is BobberBar && currentTool.isFishing)
            {
                PlayFishMinigame();
            }
            else
            {
                // Do everything else the mod does outside of the fishing game.
                // If this is the first time out of the fishing game, clear the data.
                if (this.inFishingMenu)
                {
                    log.Silly("Left Fishing minigame, clearing memory");
                    this.UnloadSVReflectionObjects();
                    this.inFishingMenu            = false;
                    IsButtonDownHack.simulateDown = false;
                }

                // This might be where a state machine might help, as an extra check, (e.g can't set power if you're not done casting, etc...)
                // but the SV tool API seems to give us enough data to have a go at it just checking conditionals.

                // Sequential steps to automate fishing
                if (config.autoCast && ShouldDoAutoCast(currentTool))
                {
                    log.Trace("Attempting to cast for the user");
                    currentTool.beginUsing(Game1.currentLocation,
                                           Game1.player.getStandingX(),
                                           Game1.player.getStandingY(),
                                           Game1.player);
                }

                if (config.maxCastPower && ShouldSetCastingPower(currentTool))
                {
                    log.Trace("Modifying cast to max cast power");
                    // Apparently for max to be registered it needs to be > 1.0, but anything over increases the
                    // power bar past the UI, so make it a small number.  Also, 1.001F is too small.
                    currentTool.castingPower = 1.01F;
                }

                if (config.quickHook && ShouldSetQuickHook(currentTool))
                {
                    log.Trace("Modifying cast so fish will bite quickly.");
                    // Game uses fishingBiteAccumulator as the value that gets modified so we should only modify that one
                    // and let the game increase it and handle logic as they become equal.  Change the gap if it doesn't
                    // generate a quick hit quick enough.
                    currentTool.fishingBiteAccumulator = currentTool.timeUntilFishingBite - fishingBiteAccumulatorGap;
                }

                if (config.autoHook && ShouldDoAutoHook(currentTool))
                {
                    log.Trace("Executing hook function for FishingRod");
                    currentTool.DoFunction(Game1.currentLocation,
                                           Game1.player.getStandingX(),
                                           Game1.player.getStandingY(),
                                           (int)currentTool.castingPower,
                                           Game1.player);
                }

                // Click away the catched fish.  The conditionals are ordered here in a way
                // the check for the popup happens before the config check so the code can
                // always check the treasure chest.  See the variable doneCaughtFish for more
                // info.
                if (ShouldDoDismissCaughtPopup(currentTool))
                {
                    log.Trace("Tool is sitting at caught fish popup");
                    doneCaughtFish = true;

                    if (config.autoFinish && config.HarmonyLoad)
                    {
                        log.Trace("Closing popup with Harmony");
                        ClickAtAllHack.simulateClick = true;
                    }
                }
                else
                {
                    if (ClickAtAllHack.simulateClick)
                    {
                        log.Trace("Turning off Harmony injection for caught fish popup");
                        ClickAtAllHack.simulateClick = false;
                    }
                }

                // Deal with any treasure that has popped up
                if (ShouldDoProcessTreasure(currentTool) && doneCaughtFish)
                {
                    log.Trace("Found treasure after the caught fish popup");
                    doneCaughtFish = false;
                    if (config.autoFinish)
                    {
                        log.Trace("Acquiring treasure");
                        ItemGrabMenu m = Game1.activeClickableMenu as ItemGrabMenu;
                        if (m.ItemsToGrabMenu != null && m.ItemsToGrabMenu.actualInventory != null)
                        {
                            if (AcquireTreasure(m.ItemsToGrabMenu.actualInventory))
                            {
                                m.exitThisMenu(true);
                            }
                            else
                            {
                                HandleItemGrabMenuError(m, "might be full inventory");
                            }
                        }
                        else
                        {
                            HandleItemGrabMenuError(m, "treasure chest is open, but inventory is null");
                        }
                    }
                }
            }
        }