public override void updateMap() { // Always create an empty map, to avoid crashes // (give it maximum size, so game doesn't mess with warp locations on network) if (this.map == null) { this.map = CreateEmptyMap("DEEPWOODSEMPTY", Settings.Map.MaxMapWidth, Settings.Map.MaxMapHeight); } // Check if level is properly initialized if (this.Seed == 0) { return; } // Check that network data has been sent and initialized by server if (!this.HasReceivedNetworkData) { return; } // Check if map is already created if (this.map != null && this.map.Id == this.Name) { return; } // Check that mapWidth and mapHeight are set if (mapWidth.Value == 0 || mapHeight.Value == 0) { return; } // Create map with proper size this.map = CreateEmptyMap(this.Name, mapWidth, mapHeight); // Build the map! ModEntry.GetAPI().CallBeforeMapGeneration(this); if (ModEntry.GetAPI().CallOverrideMapGeneration(this)) { this.isOverrideMap.Value = true; // Make sure map id is our name, otherwise game will reload the map every frame crashing the game this.map.Id = this.Name; } else { DeepWoodsBuilder.Build(this, this.map, DeepWoodsEnterExit.CreateExitDictionary(this.EnterDir, this.EnterLocation, this.exits)); } ModEntry.GetAPI().CallAfterMapGeneration(this); }
private void AddStuff() { int mapWidth = this.spaceManager.GetMapWidth(); int mapHeight = this.spaceManager.GetMapHeight(); // Add thorny bushes around exit areas. if (!deepWoods.isLichtung && deepWoods.level.Value > Settings.Level.MinLevelForThornyBushes) { foreach (var exit in deepWoods.exits) { if (this.random.CheckChance(Settings.Level.ChanceForThornyBushesOnExit)) { AddThornyBushesToExit(exit); } } } if (deepWoods.isLichtung) { // Add something awesome in the lichtung center AddSomethingAwesomeForLichtung(new Vector2(deepWoods.lichtungCenter.X, deepWoods.lichtungCenter.Y)); } if (!deepWoods.isLichtung && deepWoods.level.Value >= Settings.Level.MinLevelForGingerbreadHouse && this.random.CheckChance(Settings.Luck.Terrain.ChanceForGingerbreadHouse)) { // Add a gingerbread house deepWoods.resourceClumps.Add(new GingerBreadHouse(new Vector2(mapWidth / 2, mapHeight / 2))); } int numEasterEggs = 0; int maxEasterEggs = 0; if (IsEasterEggDay()) { maxEasterEggs = 1 + this.random.GetRandomValue(Settings.Luck.Terrain.MaxEasterEggsPerLevel); if (this.random.CheckChance(Settings.Luck.Terrain.ChanceForExtraEasterEgg)) { maxEasterEggs++; } if (!this.random.CheckChance(Settings.Luck.Terrain.ChanceForEasterEggsDoubled)) { maxEasterEggs = Math.Max(1, maxEasterEggs / 2); } } List <int> allTilesInRandomOrder = Enumerable.Range(0, mapWidth * mapHeight).OrderBy(n => Game1.random.Next()).ToList(); // Calculate maximum theoretical amount of terrain features for the current map. int maxTerrainFeatures = (mapWidth * mapHeight) / MINIMUM_TILES_FOR_TERRAIN_FEATURE; int i = 0; for (; i < maxTerrainFeatures; i++) { // int x = this.random.GetRandomValue(1, mapWidth - 1); // int y = this.random.GetRandomValue(1, mapHeight - 1); int tileIndex = allTilesInRandomOrder[i]; int x = tileIndex % mapWidth; int y = tileIndex / mapWidth; Vector2 location = new Vector2(x, y); // Check if location is free if (/*deepWoods.terrainFeatures.ContainsKey(location) ||*/ !deepWoods.isTileLocationTotallyClearAndPlaceable(location)) { continue; } // Don't place anything on the bright grass in Lichtungen if (deepWoods.isLichtung && DeepWoodsBuilder.IsTileIndexBrightGrass(deepWoods.map.GetLayer("Back").Tiles[x, y]?.TileIndex ?? 0)) { continue; } // Don't place anything on water if (deepWoods.doesTileHaveProperty(x, y, "Water", "Back") != null) { continue; } if (deepWoods.isLichtung) { if (this.random.CheckChance(Settings.Luck.Terrain.ChanceForFlowerOnClearing)) { deepWoods.terrainFeatures[location] = new Flower(GetRandomFlowerType(), location); } else if (IsEasterEggDay() && numEasterEggs < maxEasterEggs && this.random.CheckChance(Settings.Luck.Terrain.ChanceForEasterEgg)) { deepWoods.terrainFeatures[location] = new EasterEgg(); numEasterEggs++; } else { AddModOrGrass(location); } } else { if (deepWoods.level.Value >= Settings.Level.MinLevelForMeteorite && this.random.CheckChance(Settings.Luck.Terrain.ResourceClump.ChanceForMeteorite) && IsSpaceFree(location, new Size(2, 2))) { deepWoods.resourceClumps.Add(new ExplodableResourceClump(ResourceClump.meteoriteIndex, 2, 2, location)); } else if (this.random.CheckChance(Settings.Luck.Terrain.ResourceClump.ChanceForBoulder) && IsSpaceFree(location, new Size(2, 2))) { deepWoods.resourceClumps.Add(new ExplodableResourceClump(this.random.CheckChance(Chance.FIFTY_FIFTY) ? ResourceClump.mineRock1Index : ResourceClump.mineRock2Index, 2, 2, location)); } else if (this.random.CheckChance(Settings.Luck.Terrain.ResourceClump.ChanceForHollowLog) && IsSpaceFree(location, new Size(2, 2))) { deepWoods.resourceClumps.Add(new ExplodableResourceClump(ResourceClump.hollowLogIndex, 2, 2, location)); } else if (this.random.CheckChance(Settings.Luck.Terrain.ResourceClump.ChanceForStump) && IsSpaceFree(location, new Size(2, 2))) { deepWoods.resourceClumps.Add(new ExplodableResourceClump(ResourceClump.stumpIndex, 2, 2, location)); } else if (this.random.CheckChance(Settings.Luck.Terrain.ChanceForLargeBush) && IsSpaceFree(location, new Size(3, 1))) { deepWoods.largeTerrainFeatures.Add(new DestroyableBush(location, Bush.largeBush, deepWoods)); } else if (this.random.CheckChance(Settings.Luck.Terrain.ChanceForMediumBush) && IsSpaceFree(location, new Size(2, 1))) { deepWoods.largeTerrainFeatures.Add(new DestroyableBush(location, Bush.mediumBush, deepWoods)); } else if (this.random.CheckChance(Settings.Luck.Terrain.ChanceForSmallBush)) { deepWoods.largeTerrainFeatures.Add(new DestroyableBush(location, Bush.smallBush, deepWoods)); } else if (this.random.CheckChance(Settings.Luck.Terrain.ChanceForGrownTree) && IsRegionTreeFree(location, 1)) { deepWoods.terrainFeatures[location] = new Tree(GetRandomTreeType(), Tree.treeStage); } else if (this.random.CheckChance(Settings.Luck.Terrain.ChanceForMediumTree)) { deepWoods.terrainFeatures[location] = new Tree(GetRandomTreeType(), Tree.bushStage); } else if (this.random.CheckChance(Settings.Luck.Terrain.ChanceForSmallTree)) { deepWoods.terrainFeatures[location] = new Tree(GetRandomTreeType(), this.random.GetRandomValue(Tree.sproutStage, Tree.saplingStage)); } else if (this.random.CheckChance(Settings.Luck.Terrain.ChanceForGrownFruitTree) && IsRegionTreeFree(location, 2)) { int numFruits = 0; if (deepWoods.level.Value >= Settings.Level.MinLevelForFruits) { numFruits = this.random.GetRandomValue(Settings.Luck.Terrain.FruitCount); } AddFruitTree(location, FruitTree.treeStage, numFruits); } else if (this.random.CheckChance(Settings.Luck.Terrain.ChanceForSmallFruitTree)) { AddFruitTree(location, FruitTree.bushStage); } else if (this.random.CheckChance(Settings.Luck.Terrain.ChanceForWeed)) { deepWoods.objects[location] = new StardewValley.Object(location, GetRandomWeedType(), 1); } else if (this.random.CheckChance(Settings.Luck.Terrain.ChanceForTwig)) { deepWoods.objects[location] = new StardewValley.Object(location, GetRandomTwigType(), 1); } else if (this.random.CheckChance(Settings.Luck.Terrain.ChanceForStone)) { deepWoods.objects[location] = new StardewValley.Object(location, GetRandomStoneType(), 1); } else if (this.random.CheckChance(Settings.Luck.Terrain.ChanceForMushroom)) { deepWoods.objects[location] = new StardewValley.Object(location, GetRandomMushroomType(), 1) { IsSpawnedObject = true }; } else if (deepWoods.level.Value >= Settings.Level.MinLevelForFlowers && this.random.CheckChance(Game1.currentSeason == "winter" ? Settings.Luck.Terrain.ChanceForFlowerInWinter : Settings.Luck.Terrain.ChanceForFlower)) { deepWoods.terrainFeatures[location] = new Flower(GetRandomFlowerType(), location); } else if (IsEasterEggDay() && numEasterEggs < maxEasterEggs && this.random.CheckChance(Settings.Luck.Terrain.ChanceForEasterEgg)) { deepWoods.terrainFeatures[location] = new EasterEgg(); numEasterEggs++; } else { AddModOrGrass(location); } } } // Fill up with grass (if not a Lichtung) if (!deepWoods.isLichtung) { int maxGrass = (allTilesInRandomOrder.Count() - maxTerrainFeatures) / 3; if (Game1.currentSeason == "winter") { // Leaveless trees and snow ground make winter forest look super empty and open, // so we fill it with plenty of icy grass to give it a better atmosphere. maxGrass *= 2; } for (int j = 0; j < maxGrass; j++, i++) { int tileIndex = allTilesInRandomOrder[i]; int x = tileIndex % mapWidth; int y = tileIndex / mapWidth; Vector2 location = new Vector2(x, y); if (/*deepWoods.terrainFeatures.ContainsKey(location) ||*/ !deepWoods.isTileLocationTotallyClearAndPlaceable(location)) { continue; } deepWoods.terrainFeatures[location] = new LootFreeGrass(GetSeasonGrassType(), this.random.GetRandomValue(1, 3)); } } }