public override void emergencyShutDown()
        {
            // Failed to catch fish
            if (!this._notifiedFailOrSucceed)
            {
                this._notifiedFailOrSucceed = true;
                ModFishing.Instance.Api.SetStreak(this.User, 0);
                if (this._origStreak >= ModFishing.Instance.MainConfig.StreakSettings.StreakForIncreasedQuality)
                {
                    Game1.showGlobalMessage(ModFishing.Translate("text.lostStreak", this._origStreak));
                }
            }

            base.emergencyShutDown();
        }
Esempio n. 2
0
        private void PostRenderHud(object sender, EventArgs eventArgs)
        {
            if (!this.MainConfig.ShowFishingData || Game1.eventUp || !(Game1.player.CurrentTool is FishingRod rod))
            {
                return;
            }

            Color      textColor = Color.White;
            SpriteFont font      = Game1.smallFont;

            // Draw the fishing GUI to the screen
            float   boxWidth      = 0;
            float   lineHeight    = font.LineSpacing;
            Vector2 boxTopLeft    = new Vector2(this.MainConfig.HudTopLeftX, this.MainConfig.HudTopLeftY);
            Vector2 boxBottomLeft = boxTopLeft;

            // Setup the sprite batch
            SpriteBatch batch = Game1.spriteBatch;

            batch.End();
            batch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);

            // Draw streak
            string streakText = ModFishing.Translate("text.streak", this.Api.GetStreak(Game1.player));

            batch.DrawStringWithShadow(font, streakText, boxBottomLeft, textColor, 1f);
            boxWidth       = Math.Max(boxWidth, font.MeasureString(streakText).X);
            boxBottomLeft += new Vector2(0, lineHeight);

            // Get info on all the possible fish
            IWeightedElement <int?>[] possibleFish = this.Api.GetPossibleFish(Game1.player).Where(e => e.Value != null).ToArray();
            double fishChance = possibleFish.SumWeights();

            // Limit the number of displayed fish
            int trimmed = possibleFish.Length - 5;

            if (trimmed > 1)
            {
                possibleFish = possibleFish.Take(5).ToArray();
            }

            // Draw treasure chance
            string treasureText = ModFishing.Translate("text.treasure", ModFishing.Translate("text.percent", this.Api.GetTreasureChance(Game1.player, rod)));

            batch.DrawStringWithShadow(font, treasureText, boxBottomLeft, textColor, 1f);
            boxWidth       = Math.Max(boxWidth, font.MeasureString(treasureText).X);
            boxBottomLeft += new Vector2(0, lineHeight);

            // Draw trash chance
            string trashText = ModFishing.Translate("text.trash", ModFishing.Translate("text.percent", 1f - fishChance));

            batch.DrawStringWithShadow(font, trashText, boxBottomLeft, textColor, 1f);
            boxWidth       = Math.Max(boxWidth, font.MeasureString(trashText).X);
            boxBottomLeft += new Vector2(0, lineHeight);

            if (possibleFish.Any())
            {
                // Draw info for each fish
                const float iconScale = Game1.pixelZoom / 2f;
                foreach (IWeightedElement <int?> fishData in possibleFish)
                {
                    // Skip trash
                    if (fishData.Value == null)
                    {
                        continue;
                    }

                    // Get fish ID
                    int fish = fishData.Value.Value;

                    // Don't draw hidden fish
                    if (this.Api.IsHidden(fish))
                    {
                        continue;
                    }

                    // Draw fish icon
                    Rectangle source = GameLocation.getSourceRectForObject(fish);
                    batch.Draw(Game1.objectSpriteSheet, boxBottomLeft, source, Color.White, 0.0f, Vector2.Zero, iconScale, SpriteEffects.None, 1F);
                    lineHeight = Math.Max(lineHeight, source.Height * iconScale);

                    // Draw fish information
                    string chanceText = ModFishing.Translate("text.percent", fishData.GetWeight());
                    string fishText   = $"{this.Api.GetFishName(fish)} - {chanceText}";
                    batch.DrawStringWithShadow(font, fishText, boxBottomLeft + new Vector2(source.Width * iconScale, 0), textColor, 1F);
                    boxWidth = Math.Max(boxWidth, font.MeasureString(fishText).X + source.Width * iconScale);

                    // Update destY
                    boxBottomLeft += new Vector2(0, lineHeight);
                }
            }

            if (trimmed > 0)
            {
                batch.DrawStringWithShadow(font, $"+{trimmed}...", boxBottomLeft, textColor, 1f);
                boxBottomLeft += new Vector2(0, lineHeight);
            }

            // Draw the background rectangle
            batch.Draw(DrawHelpers.WhitePixel, new Rectangle((int)boxTopLeft.X, (int)boxTopLeft.Y, (int)boxWidth, (int)boxBottomLeft.Y), null, new Color(0, 0, 0, 0.25F), 0f, Vector2.Zero, SpriteEffects.None, 0.85F);

            // Debug info
            StringBuilder text = new StringBuilder();

            if (text.Length > 0)
            {
                batch.DrawStringWithShadow(Game1.smallFont, text.ToString(), boxBottomLeft, Color.White, 0.8F);
            }

            batch.End();
            batch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullCounterClockwise);
        }
        public CustomBobberBar(Farmer user, int whichFish, float fishSize, bool treasure, int bobber) : base(whichFish, fishSize, treasure, bobber)
        {
            this.User        = user;
            this._origStreak = ModFishing.Instance.Api.GetStreak(user);
            this._origFish   = whichFish;

            /* Private field hooks */
            this._treasure            = new ReflectedField <BobberBar, bool>(this, "treasure");
            this._treasure            = new ReflectedField <BobberBar, bool>(this, "treasure");
            this._treasureCaught      = new ReflectedField <BobberBar, bool>(this, "treasureCaught");
            this._treasurePosition    = new ReflectedField <BobberBar, float>(this, "treasurePosition");
            this._treasureAppearTimer = new ReflectedField <BobberBar, float>(this, "treasureAppearTimer");
            this._treasureScale       = new ReflectedField <BobberBar, float>(this, "treasureScale");

            this._distanceFromCatching = new ReflectedField <BobberBar, float>(this, "distanceFromCatching");
            this._treasureCatchLevel   = new ReflectedField <BobberBar, float>(this, "treasureCatchLevel");

            this._bobberBarPos    = new ReflectedField <BobberBar, float>(this, "bobberBarPos");
            this._bobberInBar     = new ReflectedField <BobberBar, bool>(this, "bobberInBar");
            this._difficulty      = new ReflectedField <BobberBar, float>(this, "difficulty");
            this._fishQuality     = new ReflectedField <BobberBar, int>(this, "fishQuality");
            this._perfect         = new ReflectedField <BobberBar, bool>(this, "perfect");
            this._scale           = new ReflectedField <BobberBar, float>(this, "scale");
            this._flipBubble      = new ReflectedField <BobberBar, bool>(this, "flipBubble");
            this._bobberBarHeight = new ReflectedField <BobberBar, int>(this, "bobberBarHeight");
            this._reelRotation    = new ReflectedField <BobberBar, float>(this, "reelRotation");
            this._bobberPosition  = new ReflectedField <BobberBar, float>(this, "bobberPosition");
            this._bossFish        = new ReflectedField <BobberBar, bool>(this, "bossFish");
            this._motionType      = new ReflectedField <BobberBar, int>(this, "motionType");
            this._fishSize        = new ReflectedField <BobberBar, int>(this, "fishSize");
            this._whichFish       = new ReflectedField <BobberBar, int>(this, "whichFish");

            this._barShake        = new ReflectedField <BobberBar, Vector2>(this, "barShake");
            this._fishShake       = new ReflectedField <BobberBar, Vector2>(this, "fishShake");
            this._treasureShake   = new ReflectedField <BobberBar, Vector2>(this, "treasureShake");
            this._everythingShake = new ReflectedField <BobberBar, Vector2>(this, "everythingShake");

            this._sparkleText = new ReflectedField <BobberBar, SparklingText>(this, "sparkleText");

            this._lastDistanceFromCatching = this._distanceFromCatching.Value;
            this._lastTreasureCatchLevel   = this._treasureCatchLevel.Value;

            /* Actual code */
            ConfigMain  config = ModFishing.Instance.MainConfig;
            IFishTraits traits = ModFishing.Instance.Api.GetFishTraits(whichFish);

            // Check if fish is unaware
            this.Unaware = Game1.random.NextDouble() < ModFishing.Instance.Api.GetUnawareChance(user, whichFish);

            // Applies difficulty modifier, including if fish is unaware
            float difficulty = traits?.Difficulty ?? this._difficulty.Value;

            difficulty *= config.DifficultySettings.BaseDifficultyMult;
            difficulty *= 1F + this._origStreak * config.DifficultySettings.DifficultyStreakEffect;
            if (this.Unaware)
            {
                difficulty *= config.UnawareSettings.UnawareMult;
                Game1.showGlobalMessage(ModFishing.Translate("text.unaware", ModFishing.Translate("text.percent", 1F - config.UnawareSettings.UnawareMult)));
            }
            this._difficulty.Value = difficulty;

            // Adjusts additional traits about the fish
            if (traits != null)
            {
                this._motionType.Value = (int)traits.MotionType;
                this._fishSize.Value   = traits.MinSize + (int)((traits.MaxSize - traits.MinSize) * fishSize) + 1;
            }

            // Adjusts quality to be increased by streak
            int fishQuality = this._fishQuality.Value;

            this._origQuality = fishQuality;
            int qualityBonus = (int)Math.Floor((double)this._origStreak / config.StreakSettings.StreakForIncreasedQuality);

            fishQuality = Math.Min(fishQuality + qualityBonus, 3);
            if (fishQuality == 3)
            {
                fishQuality++;                   // Iridium-quality fish. Only possible through your perfect streak
            }
            this._fishQuality.Value = fishQuality;

            // Increase the user's perfect streak (this will be dropped to 0 if they don't get a perfect catch)
            if (this._origStreak >= config.StreakSettings.StreakForIncreasedQuality)
            {
                this._sparkleText.Value = new SparklingText(Game1.dialogueFont, ModFishing.Translate("text.streak", this._origStreak), Color.Yellow, Color.White);
            }
        }
        public override void update(GameTime time)
        {
            // Speed warp on catching fish
            float distanceFromCatching = this._distanceFromCatching.Value;
            float delta = distanceFromCatching - this._lastDistanceFromCatching;
            float mult  = delta > 0 ? ModFishing.Instance.MainConfig.DifficultySettings.CatchSpeed : ModFishing.Instance.MainConfig.DifficultySettings.DrainSpeed;

            distanceFromCatching             = this._lastDistanceFromCatching + delta * mult;
            this._lastDistanceFromCatching   = distanceFromCatching;
            this._distanceFromCatching.Value = distanceFromCatching;

            // Speed warp on catching treasure
            float treasureCatchLevel = this._treasureCatchLevel.Value;

            delta = treasureCatchLevel - this._lastTreasureCatchLevel;
            mult  = delta > 0 ? ModFishing.Instance.MainConfig.DifficultySettings.TreasureCatchSpeed : ModFishing.Instance.MainConfig.DifficultySettings.TreasureDrainSpeed;
            treasureCatchLevel             = this._lastTreasureCatchLevel + delta * mult;
            this._lastTreasureCatchLevel   = treasureCatchLevel;
            this._treasureCatchLevel.Value = treasureCatchLevel;

            bool perfect        = this._perfect.Value;
            bool treasure       = this._treasure.Value;
            bool treasureCaught = this._treasureCaught.Value;

            // Check if still perfect, otherwise apply changes to loot
            if (!this._perfectChanged && !perfect)
            {
                this._perfectChanged    = true;
                this._fishQuality.Value = Math.Min(this._origQuality, ModFishing.Instance.MainConfig.DifficultySettings.PreventGoldOnNormalCatch ? 1 : 2);
                ModFishing.Instance.Api.SetStreak(this.User, 0);
                if (this._origStreak >= ModFishing.Instance.MainConfig.StreakSettings.StreakForIncreasedQuality)
                {
                    Game1.showGlobalMessage(ModFishing.Translate(treasure ? "text.warnStreak" : "text.lostStreak", this._origStreak));
                }
            }

            // Check if lost perfect, but got treasure
            if (!this._treasureChanged && !perfect && treasure && treasureCaught)
            {
                this._treasureChanged = true;
                int qualityBonus = (int)Math.Floor((double)this._origStreak / ModFishing.Instance.MainConfig.StreakSettings.StreakForIncreasedQuality);
                int quality      = this._origQuality;
                quality = Math.Min(quality + qualityBonus, 3);
                if (quality == 3)
                {
                    quality++;
                }
                this._fishQuality.Value = quality;
            }

            // Base call
            base.update(time);

            // Check if done fishing
            distanceFromCatching = this._distanceFromCatching.Value;
            if (this._notifiedFailOrSucceed)
            {
                return;
            }

            if (distanceFromCatching <= 0.0)
            {
                // Failed to catch fish
                this._notifiedFailOrSucceed = true;

                if (treasure)
                {
                    this._notifiedFailOrSucceed = true;
                    if (this._origStreak >= ModFishing.Instance.MainConfig.StreakSettings.StreakForIncreasedQuality)
                    {
                        Game1.showGlobalMessage(ModFishing.Translate("text.lostStreak", this._origStreak));
                    }
                }
            }
            else if (distanceFromCatching >= 1.0)
            {
                // Succeeded in catching the fish
                this._notifiedFailOrSucceed = true;

                if (perfect)
                {
                    ModFishing.Instance.Api.SetStreak(this.User, this._origStreak + 1);
                }
                else if (treasure && treasureCaught)
                {
                    if (this._origStreak >= ModFishing.Instance.MainConfig.StreakSettings.StreakForIncreasedQuality)
                    {
                        Game1.showGlobalMessage(ModFishing.Translate("text.keptStreak", this._origStreak));
                    }
                    ModFishing.Instance.Api.SetStreak(this.User, this._origStreak);
                }

                // Invoke fish caught event
                int curFish = this._whichFish.Value;
                FishingEventArgs eventArgs = new FishingEventArgs(curFish, this.User, this.User.CurrentTool as FishingRod);
                ModFishing.Instance.Api.OnFishCaught(eventArgs);
                if (eventArgs.ParentSheetIndex != curFish)
                {
                    this._whichFish.Value = eventArgs.ParentSheetIndex;
                }
            }
        }