예제 #1
0
        public override void performTenMinuteUpdate(int timeOfDay)
        {
            base.performTenMinuteUpdate(timeOfDay);

            Random random = new Random(timeOfDay + (int)Game1.uniqueIDForThisGame / 2 + (int)Game1.stats.DaysPlayed);

            // Fishing
            if (this.fishSplashPoint.Value.Equals(Point.Zero) && random.NextDouble() < type.Behavior.FishingSplashChance)
            {
                for (int index = 0; index < 2; ++index)
                {
                    Point point = new Point(random.Next(0, this.map.GetLayer("Back").LayerWidth), random.Next(0, this.map.GetLayer("Back").LayerHeight));
                    if (this.isOpenWater(point.X, point.Y))
                    {
                        int land = FishingRod.distanceToLand(point.X, point.Y, this);
                        if (land > 1 && land <= 5)
                        {
                            if (Game1.player.currentLocation.Equals((object)this))
                            {
                                Game1.playSound("waterSlosh");
                            }
                            this.fishSplashPoint.Value = point;
                            this.fishSplashAnimation   = new TemporaryAnimatedSprite(51, new Vector2((float)(point.X * Game1.tileSize), (float)(point.Y * Game1.tileSize)), Color.White, 10, false, 80f, 999999, -1, -1f, -1, 0);
                            break;
                        }
                    }
                }
            }
        }
예제 #2
0
 public override void performOrePanTenMinuteUpdate(Random r)
 {
     if (Game1.MasterPlayer.mailReceived.Contains("ccFishTank") && orePanPoint.Value.Equals(Point.Zero) && r.NextDouble() < 0.5)
     {
         int   tries = 0;
         Point p;
         while (true)
         {
             if (tries >= 6)
             {
                 return;
             }
             p = new Point(r.Next(4, 15), r.Next(45, 70));
             if (isOpenWater(p.X, p.Y) && FishingRod.distanceToLand(p.X, p.Y, this) <= 1 && getTileIndexAt(p, "Buildings") == -1)
             {
                 break;
             }
             tries++;
         }
         if (Game1.player.currentLocation.Equals(this))
         {
             playSound("slosh");
         }
         orePanPoint.Value = p;
     }
     else if (!orePanPoint.Value.Equals(Point.Zero) && r.NextDouble() < 0.1)
     {
         orePanPoint.Value = Point.Zero;
     }
 }
예제 #3
0
        private void CreatePanningSpot(GameLocation location)
        {
            Random random = new Random(Game1.timeOfDay + (int)Game1.uniqueIDForThisGame / 2 + (int)Game1.stats.DaysPlayed);
            //List<Point> possibleTiles = openWaterTiles[location.Name];
            var possibleTiles = openWaterTiles[location.Name];

            if (possibleTiles.OreSpots.Count != 0)
            {
                for (int i = 0; i < 4; i++) // should only ever need to try once, but just in case...
                {
                    int   indx        = random.Next(0, possibleTiles.OreSpots.Count);
                    Point newOrePoint = possibleTiles.OreSpots[indx];

                    // Double check to make sure it's a valid point/tile
                    if (location.isOpenWater(newOrePoint.X, newOrePoint.Y) && FishingRod.distanceToLand(newOrePoint.X, newOrePoint.Y, location) <= 0)
                    {
                        if (Game1.player.currentLocation.Equals(location) && config.enableSplashSounds)
                        {
                            location.playSound("slosh");
                        }

                        location.orePanPoint.Value      = newOrePoint;
                        hasPanningSpot                  = true;
                        playerPannedSpot                = false;
                        modCreatedPanningSpot[location] = true;

                        if (i > 0)
                        {
                            this.Monitor.Log($"Had to loop... check data file {location}.json");
                        }
                        break;
                    }
                }
            }
        }
예제 #4
0
        public override void performTenMinuteUpdate(int timeOfDay)
        {
            base.performTenMinuteUpdate(timeOfDay);
            Random r = new Random(timeOfDay + (int)Game1.uniqueIDForThisGame / 2 + (int)Game1.stats.DaysPlayed);

            if (fishSplashPoint.Value.Equals(Point.Zero) && r.NextDouble() < 1.0 && curtainOpenPercent >= 1f)
            {
                for (int tries = 0; tries < 2; tries++)
                {
                    Point p = new Point(r.Next(9, 21), r.Next(7, 12));
                    if (!isOpenWater(p.X, p.Y))
                    {
                        continue;
                    }
                    int toLand = FishingRod.distanceToLand(p.X, p.Y, this);
                    if (toLand > 1 && toLand < 5)
                    {
                        if (Game1.player.currentLocation.Equals(this))
                        {
                            playSound("waterSlosh");
                        }
                        fishSplashPoint.Value = p;
                        break;
                    }
                }
            }
            else if (!fishSplashPoint.Value.Equals(Point.Zero) && r.NextDouble() < 0.25)
            {
                fishSplashPoint.Value = Point.Zero;
            }
        }
예제 #5
0
        private void UpdatePossibleTiles(GameLocation currentLocation)
        {
            if (!openWaterTiles.ContainsKey(currentLocation.Name))
            {
                string file = Path.Combine("DataFiles", $"{currentLocation.Name}.json");
                if (currentLocation.Name == "Farm")   // Special Case
                {
                    file = Path.Combine("DataFiles", farmFile);
                }

                //List<Point> possibleTiles = this.Helper.Data.ReadJsonFile<List<Point>>(file);
                var mapOreConfig = this.Helper.Data.ReadJsonFile <MapOreConfig>(file);

                if (mapOreConfig == null) //No file was found...
                {
                    mapOreConfig = new MapOreConfig()
                    {
                        AreaName = currentLocation.Name, numberOfOreSpotsPerDay = config.maxNumberOfOrePointsGathered
                    };

                    var possibleTiles = new List <Point>();

                    int maxWidth  = currentLocation.Map.GetLayer("Back").LayerWidth;
                    int maxHeight = currentLocation.Map.GetLayer("Back").LayerHeight;
                    for (int width = 0; width < maxWidth; width++)
                    {
                        for (int height = 0; height < maxHeight; height++)
                        {
                            Point possibleOrePoint = new Point(width, height);
                            if (currentLocation.isOpenWater(width, height) && FishingRod.distanceToLand(width, height, currentLocation) <= 0)
                            {
                                possibleTiles.Add(possibleOrePoint);
                            }
                        }
                    }

                    mapOreConfig.OreSpots = possibleTiles;

                    if (!currentLocation.Name.Contains("UndergroundMine"))
                    {
                        this.Helper.Data.WriteJsonFile(file, mapOreConfig); // Write out new file since we had to try and find spawn points.
                    }
                    else if (currentLocation.Name == "UndergroundMine20" ||
                             currentLocation.Name == "UndergroundMine60" ||
                             currentLocation.Name == "UndergroundMine100")
                    {
                        this.Helper.Data.WriteJsonFile(file, mapOreConfig); // The only mine levels with water
                    }
                }
                openWaterTiles.Add(currentLocation.Name, mapOreConfig);
            }
        }
예제 #6
0
        private void StartMinigameEndFunction(FishingRod rod, Farmer user, int fish)
        {
            rod.isReeling = true;
            rod.hit       = false;

            // Animation
            switch (user.FacingDirection)
            {
            case 1:
                user.FarmerSprite.setCurrentSingleFrame(48);
                break;

            case 3:
                user.FarmerSprite.setCurrentSingleFrame(48, 32000, false, true);
                break;

            default:
                break;
            }
            user.FarmerSprite.PauseForSingleAnimation = true;

            // Distance from bobber to land
            IReflectedField <int> clearWaterDistanceField = ModFishing.Instance.Helper.Reflection.GetField <int>(rod, "clearWaterDistance");

            clearWaterDistanceField.SetValue(FishingRod.distanceToLand((int)(rod.bobber.X / 64.0 - 1.0), (int)(rod.bobber.Y / 64.0 - 1.0), user.currentLocation));

            // Calculate size of fish
            float num = 1f * (clearWaterDistanceField.GetValue() / 5f) * (Game1.random.Next(1 + Math.Min(10, user.FishingLevel) / 2, 6) / 5f);

            if (rod.favBait)
            {
                num *= 1.2f;
            }
            float fishSize = Math.Max(0.0f, Math.Min(1f, num * (float)(1.0 + Game1.random.Next(-10, 10) / 100.0)));

            // Check if there should be treasure
            bool treasure = !Game1.isFestival();

            treasure &= user.fishCaught != null && user.fishCaught.Count > 1;
            treasure &= Game1.random.NextDouble() < ModFishing.Instance.Api.GetTreasureChance(user, rod);
            Game1.activeClickableMenu = new CustomBobberBar(user, fish, fishSize, treasure, rod.attachments[1]?.ParentSheetIndex ?? -1);
        }
예제 #7
0
 protected void addMoonlightJellies(int numTries, Random r, Microsoft.Xna.Framework.Rectangle exclusionRect)
 {
     for (int i = 0; i < numTries; i++)
     {
         Point tile = new Point(r.Next(base.Map.Layers[0].LayerWidth), r.Next(base.Map.Layers[0].LayerHeight));
         if (!isOpenWater(tile.X, tile.Y) || exclusionRect.Contains(tile) || FishingRod.distanceToLand(tile.X, tile.Y, this) < 2)
         {
             continue;
         }
         bool tooClose = false;
         foreach (TemporaryAnimatedSprite t in underwaterSprites)
         {
             Point otherTile = new Point((int)t.position.X / 64, (int)t.position.Y / 64);
             if (Utility.distance(tile.X, otherTile.X, tile.Y, otherTile.Y) <= 2f)
             {
                 tooClose = true;
                 break;
             }
         }
         if (!tooClose)
         {
             underwaterSprites.Add(new TemporaryAnimatedSprite("Maps\\Festivals", new Microsoft.Xna.Framework.Rectangle((r.NextDouble() < 0.2) ? 304 : 256, (r.NextDouble() < 0.01) ? 32 : 16, 16, 16), 250f, 3, 9999, new Vector2(tile.X, tile.Y) * 64f, flicker: false, flipped: false, 0.1f, 0f, Color.White * 0.66f, 4f, 0f, 0f, 0f)
             {
                 yPeriodic         = (Game1.random.NextDouble() < 0.76),
                 yPeriodicRange    = 12f,
                 yPeriodicLoopTime = Game1.random.Next(5500, 8000),
                 xPeriodic         = (Game1.random.NextDouble() < 0.76),
                 xPeriodicLoopTime = Game1.random.Next(5500, 8000),
                 xPeriodicRange    = 16f,
                 light             = true,
                 lightcolor        = Color.Black,
                 lightRadius       = 1f,
                 pingPong          = true
             });
         }
     }
 }
예제 #8
0
        private void UpdatePossibleTiles(GameLocation currentLocation)
        {
            if (!openWaterTiles.ContainsKey(currentLocation.Name))
            {
                string file = Path.Combine("DataFiles", $"{currentLocation.Name}.json");
                if (currentLocation.Name == "Farm")  // Special Case
                {
                    file = Path.Combine("DataFiles", farmFile);
                }

                MapOreConfig mapOreConfig = null;
                try
                {
                    mapOreConfig = this.Helper.Data.ReadJsonFile <MapOreConfig>(file);
                }
                catch
                {
                }
                if (mapOreConfig == null) //No file was found or old file...
                {
                    List <Point> possibleTiles = null;

                    try // Trying to see if there is an old file...
                    {
                        possibleTiles = this.Helper.Data.ReadJsonFile <List <Point> >(file);
                    }
                    catch
                    {
                    }


                    mapOreConfig = new MapOreConfig()
                    {
                        FileVersion            = 1,
                        AreaName               = currentLocation.Name,
                        NumberOfOreSpotsPerDay = config.maxNumberOfOrePointsGathered,
                        StartTime              = 0600,
                        EndTime        = 2600,
                        CustomTreasure = false
                    };

                    if (possibleTiles == null)
                    {
                        possibleTiles = new List <Point>();
                        int maxWidth  = currentLocation.Map.GetLayer("Back").LayerWidth;
                        int maxHeight = currentLocation.Map.GetLayer("Back").LayerHeight;
                        for (int width = 0; width < maxWidth; width++)
                        {
                            for (int height = 0; height < maxHeight; height++)
                            {
                                Point possibleOrePoint = new Point(width, height);
                                if (currentLocation.isWaterTile(width, height) && FishingRod.distanceToLand(width, height, currentLocation) <= 0)
                                {
                                    possibleTiles.Add(possibleOrePoint);
                                }
                            }
                        }
                    }

                    mapOreConfig.OreSpots = possibleTiles;

                    if (!currentLocation.Name.Contains("UndergroundMine"))
                    {
                        this.Helper.Data.WriteJsonFile(file, mapOreConfig); // Write out new file since we had to try and find spawn points.
                    }
                    else if (currentLocation.Name == "UndergroundMine20" ||
                             currentLocation.Name == "UndergroundMine60" ||
                             currentLocation.Name == "UndergroundMine100")
                    {
                        this.Helper.Data.WriteJsonFile(file, mapOreConfig); // The only mine levels with water
                    }
                }
                if (mapOreConfig.FileVersion == 0)
                {
                    mapOreConfig.FileVersion    = 1;
                    mapOreConfig.AreaName       = currentLocation.Name;
                    mapOreConfig.StartTime      = 600;
                    mapOreConfig.EndTime        = 2600;
                    mapOreConfig.CustomTreasure = false;
                    this.Helper.Data.WriteJsonFile(file, mapOreConfig);
                }

                if (mapOreConfig.CustomTreasure)
                {
                    string treasureFile  = Path.Combine("DataFiles", $"{currentLocation.Name}_Treasure.json");
                    var    tresureGroups = this.Helper.Data.ReadJsonFile <Dictionary <TREASURE_GROUP, TreasureGroup> >(treasureFile) ?? TreasureGroupDefaultConfig.CreateTreasureGroup(treasureFile);
                    areaTreasureGroups.Add(currentLocation.Name, tresureGroups);
                }
                openWaterTiles.Add(currentLocation.Name, mapOreConfig);
            }
        }
예제 #9
0
        public static void StartMinigameEndFunction(FishingRod rod, int extra)
        {
            ModFishing.INSTANCE.Monitor.Log("Overriding fishing minigame", LogLevel.Trace);
            ConfigMain config   = ModFishing.INSTANCE.Config;
            SFarmer    lastUser = ModFishing.INSTANCE.Helper.Reflection.GetPrivateValue <SFarmer>(rod, "lastUser");
            Vector2    bobber   = ModFishing.INSTANCE.Helper.Reflection.GetPrivateValue <Vector2>(rod, "bobber");

            rod.isReeling = true;
            rod.hit       = false;
            switch (lastUser.FacingDirection)
            {
            case 1:
                lastUser.FarmerSprite.setCurrentSingleFrame(48, 32000, false, false);
                break;

            case 3:
                lastUser.FarmerSprite.setCurrentSingleFrame(48, 32000, false, true);
                break;
            }
            lastUser.FarmerSprite.pauseForSingleAnimation = true;

            int clearWaterDistance = FishingRod.distanceToLand((int)(bobber.X / (double)Game1.tileSize - 1.0), (int)(bobber.Y / (double)Game1.tileSize - 1.0), lastUser.currentLocation);

            FishingRodOverrides.ClearWaterDistances[lastUser] = clearWaterDistance;
            float num = 1f * (clearWaterDistance / 5f) * (Game1.random.Next(1 + Math.Min(10, lastUser.FishingLevel) / 2, 6) / 5f);

            if (rod.favBait)
            {
                num *= 1.2f;
            }
            float fishSize = Math.Max(0.0f, Math.Min(1f, num * (float)(1.0 + Game1.random.Next(-10, 10) / 100.0)));
            bool  treasure = false;

            double treasureChance = config.TreasureChance + lastUser.LuckLevel * config.TreasureLuckLevelEffect + (rod.getBaitAttachmentIndex() == 703 ? config.TreasureBaitEffect : 0.0) + (rod.getBobberAttachmentIndex() == 693 ? config.TreasureBobberEffect : 0.0) + Game1.dailyLuck * config.TreasureDailyLuckEffect + (lastUser.professions.Contains(9) ? config.TreasureChance : 0.0) + config.TreasureStreakEffect * FishHelper.GetStreak(lastUser);

            treasureChance = Math.Min(treasureChance, config.MaxTreasureChance);
            if (!Game1.isFestival() && lastUser.fishCaught != null && lastUser.fishCaught.Count > 1 && Game1.random.NextDouble() < treasureChance)
            {
                treasure = true;
            }

            // Override caught fish
            bool legendary = FishHelper.IsLegendary(extra);

            if (!config.UseVanillaFish && (!config.VanillaLegendaries || !legendary))
            {
                int origExtra = extra;
                extra = FishHelper.GetRandomFish(clearWaterDistance);
                if (FishHelper.IsTrash(extra))
                {
                    if (false) // TODO: Replace this with code relating to a config option that determines the chance you'll get fish/trash
                    {
#pragma warning disable CS0162 // Unreachable code detected
                        Game1.showGlobalMessage("No valid fish to catch! Giving junk instead.");
                        StardewValley.Object o = new StardewValley.Object(extra, 1, false, -1, 0);
                        rod.pullFishFromWater(extra, -1, 0, 0, false, false);
                        return;

#pragma warning restore CS0162 // Unreachable code detected
                    }
                    else
                    {
                        ModFishing.INSTANCE.Monitor.Log("No valid fish to catch! Using original fish instead.", LogLevel.Warn);
                        extra = origExtra;
                    }
                }
            }

            // Show custom bobber bar
            Game1.activeClickableMenu = new CustomBobberBar(lastUser, extra, fishSize, treasure, rod.attachments[1] != null ? rod.attachments[1].ParentSheetIndex : -1, clearWaterDistance);
        }