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; } } } } }
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; } }
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; } } } }
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; } }
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); } }
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); }
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 }); } } }
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); } }
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); }