diff --git a/src/main/java/biomesoplenty/api/biome/generation/GeneratorWeighted.java b/src/main/java/biomesoplenty/api/biome/generation/GeneratorWeighted.java index c499b9ad0..49236f01c 100644 --- a/src/main/java/biomesoplenty/api/biome/generation/GeneratorWeighted.java +++ b/src/main/java/biomesoplenty/api/biome/generation/GeneratorWeighted.java @@ -8,74 +8,138 @@ package biomesoplenty.api.biome.generation; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map.Entry; import java.util.Random; import net.minecraft.util.BlockPos; -import net.minecraft.util.WeightedRandom; import net.minecraft.world.World; +import biomesoplenty.api.biome.generation.GenerationManager.GeneratorFactory; import biomesoplenty.common.util.config.ConfigHelper.WrappedJsonObject; -// TODO implement so that we don't rely on minecraft WeightedRandom class and GeneratorWeightedEntry class - can be much simpler public class GeneratorWeighted extends GeneratorCustomizable { private int amountPerChunk; - private List weightedEntries = new ArrayList(); - - public GeneratorWeighted() {} + private HashMap generators = new HashMap(); + private HashMap weights = new HashMap(); + + public GeneratorWeighted() + { + // default + this(1); + } public GeneratorWeighted(int amountPerChunk) { this.amountPerChunk = amountPerChunk; } - public void add(int weight, IGenerator entry) + public void add(String name, int weight, IGenerator entry) { + if (this.generators.containsKey(name)) + { + throw new RuntimeException("A generator with name " + name + " already exists!"); + } + if (weight < 1) + { + throw new IllegalArgumentException("Generator weight must be positive"); + } entry.setStage(GeneratorStage.PARENT); - this.weightedEntries.add(new GeneratorWeightedEntry(weight, entry)); + this.generators.put(name, entry); + this.weights.put(entry, weight); } + public void clear() + { + this.generators.clear(); + this.weights.clear(); + } + + public IGenerator getGenerator(String name) + { + return this.generators.get(name); + } + + public void removeGenerator(String name) + { + IGenerator generator = this.generators.get(name); + if (generator != null) + { + this.generators.remove(name); + this.weights.remove(generator); + } + } + + public IGenerator getRandomGenerator(Random random) + { + if (this.weights.isEmpty()) {return null;} + int totalWeight = 0; + for (int weight : this.weights.values()) {totalWeight += weight;} + int j = random.nextInt(totalWeight); + for (Entry entry : this.weights.entrySet()) + { + j -= entry.getValue(); + if (j < 0) {return entry.getKey();} + } + return null; + } + + + @Override public void scatter(World world, Random random, BlockPos pos) { for (int i = 0; i < amountPerChunk; i++) { - GeneratorWeightedEntry generator = (GeneratorWeightedEntry)WeightedRandom.getRandomItem(random, this.weightedEntries); - - generator.scatter(world, random, pos); + this.getRandomGenerator(random).scatter(world, random, pos); } } @Override public boolean generate(World world, Random random, BlockPos pos) { - GeneratorWeightedEntry generator = (GeneratorWeightedEntry)WeightedRandom.getRandomItem(random, this.weightedEntries); - - return generator.generate(world, random, pos); + return this.getRandomGenerator(random).generate(world, random, pos); } + + @Override public void configure(WrappedJsonObject conf) { this.amountPerChunk = conf.getInt("amountPerChunk", this.amountPerChunk); - ArrayList weightedEntriesConf = conf.getObjectArray("weightedEntries"); - if (!weightedEntriesConf.isEmpty()) + WrappedJsonObject confGenerators = conf.getObject("generators"); + if (confGenerators != null) { - this.weightedEntries.clear(); - for (WrappedJsonObject weightedEntryConf : weightedEntriesConf) + for (String name : confGenerators.getKeys()) { - Integer weight = weightedEntryConf.getInt("weight", null); - if (weight == null || weight.intValue() < 1) {continue;} - WrappedJsonObject generatorConf = weightedEntryConf.getObject("generator"); - if (generatorConf == null) {continue;} - IGenerator generator = GenerationManager.GeneratorFactory.create(generatorConf); - if (generator == null) {continue;} - this.add(weight, generator); + if (this.generators.containsKey(name)) + { + IGenerator generator = this.getGenerator(name); + Integer weight = conf.getInt("weight", this.weights.get(generator)); + if (weight.intValue() < 1) + { + // remove this generator if the weight is zero (or negative) + this.removeGenerator(name); + } + else + { + // adjust weight + this.weights.put(generator, weight); + // configure the existing generator + generator.configure(conf); + } + } + else + { + // there was previously no generator of this name - attempt to add it + Integer weight = conf.getInt("weight", null); + IGenerator generator = GeneratorFactory.create(conf); + if (weight != null && generator != null) + { + this.add(name, weight, generator); + } + } } } - // TODO: at the moment, because the weighted entries aren't named, there's no way to just adjust one part of one of them - // The only thing you can do is replace the whole array. Perhaps should use named entries in a Map kind of arrangement - // Then they could be individually altered } } diff --git a/src/main/java/biomesoplenty/api/biome/generation/GeneratorWeightedEntry.java b/src/main/java/biomesoplenty/api/biome/generation/GeneratorWeightedEntry.java deleted file mode 100644 index 8b249ad94..000000000 --- a/src/main/java/biomesoplenty/api/biome/generation/GeneratorWeightedEntry.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * Copyright 2015, the Biomes O' Plenty Team - * - * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. - * - * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. - ******************************************************************************/ - -package biomesoplenty.api.biome.generation; - -import java.util.Random; - -import net.minecraft.util.BlockPos; -import net.minecraft.util.WeightedRandom; -import net.minecraft.world.World; -import biomesoplenty.common.util.config.ConfigHelper.WrappedJsonObject; - -public final class GeneratorWeightedEntry extends WeightedRandom.Item implements IGenerator -{ - private final String identifier; - private GeneratorStage stage; - private IGenerator wrappedGenerator; - - public GeneratorWeightedEntry() - { - this(-1, null); - } - - public GeneratorWeightedEntry(int weight, IGenerator wrappedGenerator) - { - super(weight); - - this.identifier = GeneratorRegistry.getIdentifier((Class)this.getClass()); - this.stage = GeneratorStage.PARENT; - this.wrappedGenerator = wrappedGenerator; - - if (this.identifier == null) - { - throw new RuntimeException("The identifier for " + this.getClass().getCanonicalName() + " cannot be null!"); - } - } - - @Override - public void scatter(World world, Random random, BlockPos pos) - { - this.wrappedGenerator.scatter(world, random, pos); - } - - @Override - public boolean generate(World world, Random random, BlockPos pos) - { - return this.wrappedGenerator.generate(world, random, pos); - } - - @Override - public void configure(WrappedJsonObject conf) - { - // this should never be used directly - ; - } - - - @Override - public void setStage(GeneratorStage stage) - { - this.stage = stage; - } - - @Override - public GeneratorStage getStage() - { - return this.stage; - } - - @Override - public final String getIdentifier() - { - return this.identifier; - } - - //Unnecessary, this shouldn't be used as a standard generator - @Override - public void setName(String name) {} - - @Override - public String getName() - { - return null; - } - -} diff --git a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenDenseForest.java b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenDenseForest.java index f16166177..c51389a0a 100644 --- a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenDenseForest.java +++ b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenDenseForest.java @@ -64,10 +64,10 @@ public class BiomeGenDenseForest extends BOPBiome this.addGenerator("leaves_clusters", GeneratorStage.POST, new GeneratorBush(7, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState())); GeneratorWeighted grassGenerator = new GeneratorWeighted(10); - grassGenerator.add(1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.WHEATGRASS))); - grassGenerator.add(1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.DAMPGRASS))); - grassGenerator.add(1, new GeneratorGrass(1, Blocks.tallgrass.getDefaultState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.FERN))); - grassGenerator.add(2, new GeneratorGrass(1, Blocks.tallgrass.getDefaultState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.GRASS))); + grassGenerator.add("wheatgrass", 1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.WHEATGRASS))); + grassGenerator.add("dampgrass", 1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.DAMPGRASS))); + grassGenerator.add("fern", 1, new GeneratorGrass(1, Blocks.tallgrass.getDefaultState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.FERN))); + grassGenerator.add("tallgrass", 2, new GeneratorGrass(1, Blocks.tallgrass.getDefaultState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.GRASS))); this.addGenerator("grass", GeneratorStage.GRASS, grassGenerator); this.addGenerator("amber", GeneratorStage.SAND, new GeneratorOreSingle(BOPBlocks.gem_ore.getDefaultState().withProperty(BlockGem.VARIANT, BOPGems.AMBER), 12, 4, 32)); diff --git a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenFlowerField.java b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenFlowerField.java index 85f24c2aa..a3bed9702 100644 --- a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenFlowerField.java +++ b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenFlowerField.java @@ -38,16 +38,16 @@ public class BiomeGenFlowerField extends BOPBiome this.addWeight(BiomeType.WARM, 3); GeneratorWeighted flowerGenerator = new GeneratorWeighted(999); - flowerGenerator.add(2, new GeneratorFlora(1, Blocks.red_flower.getDefaultState().withProperty(Blocks.red_flower.getTypeProperty(), EnumFlowerType.PINK_TULIP))); - flowerGenerator.add(5, new GeneratorFlora(1, Blocks.red_flower.getDefaultState().withProperty(Blocks.red_flower.getTypeProperty(), EnumFlowerType.WHITE_TULIP))); - flowerGenerator.add(7, new GeneratorFlora(1, Blocks.red_flower.getDefaultState().withProperty(Blocks.red_flower.getTypeProperty(), EnumFlowerType.ORANGE_TULIP))); - flowerGenerator.add(10, new GeneratorFlora(1, Blocks.red_flower.getDefaultState().withProperty(Blocks.red_flower.getTypeProperty(), EnumFlowerType.RED_TULIP))); + flowerGenerator.add("pink_tuilp", 2, new GeneratorFlora(1, Blocks.red_flower.getDefaultState().withProperty(Blocks.red_flower.getTypeProperty(), EnumFlowerType.PINK_TULIP))); + flowerGenerator.add("white_tulip", 5, new GeneratorFlora(1, Blocks.red_flower.getDefaultState().withProperty(Blocks.red_flower.getTypeProperty(), EnumFlowerType.WHITE_TULIP))); + flowerGenerator.add("orange_tulip", 7, new GeneratorFlora(1, Blocks.red_flower.getDefaultState().withProperty(Blocks.red_flower.getTypeProperty(), EnumFlowerType.ORANGE_TULIP))); + flowerGenerator.add("red_tulip", 10, new GeneratorFlora(1, Blocks.red_flower.getDefaultState().withProperty(Blocks.red_flower.getTypeProperty(), EnumFlowerType.RED_TULIP))); this.addGenerator("flowers", GeneratorStage.FLOWERS, flowerGenerator); GeneratorWeighted grassGenerator = new GeneratorWeighted(35); - grassGenerator.add(1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.WHEATGRASS))); - grassGenerator.add(1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.DAMPGRASS))); - grassGenerator.add(2, new GeneratorGrass(1, Blocks.tallgrass.getDefaultState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.GRASS))); + grassGenerator.add("wheatgrass", 1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.WHEATGRASS))); + grassGenerator.add("dampgrass", 1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.DAMPGRASS))); + grassGenerator.add("tallgrass", 2, new GeneratorGrass(1, Blocks.tallgrass.getDefaultState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.GRASS))); this.addGenerator("grass", GeneratorStage.GRASS, grassGenerator); this.addGenerator("peridot", GeneratorStage.SAND, new GeneratorOreSingle(BOPBlocks.gem_ore.getDefaultState().withProperty(BlockGem.VARIANT, BOPGems.PERIDOT), 12, 4, 32)); diff --git a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenLavenderFields.java b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenLavenderFields.java index 4726de996..b4c06f05d 100644 --- a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenLavenderFields.java +++ b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenLavenderFields.java @@ -47,13 +47,13 @@ public class BiomeGenLavenderFields extends BOPBiome this.addGenerator("lavender", GeneratorStage.FLOWERS, new GeneratorFlora(999, BlockBOPFlower.paging.getVariantState(BOPFlowers.LAVENDER))); GeneratorWeighted treeGenerator = new GeneratorWeighted(1); - treeGenerator.add(3, new GeneratorBasicTree(1, false, 4, 7, BlockBOPLog.paging.getVariantState(BOPWoods.JACARANDA), BlockBOPLeaves.paging.getVariantState(BOPTrees.JACARANDA))); - treeGenerator.add(1, new GeneratorBigTree(1, false, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState())); + treeGenerator.add("jacaranda", 3, new GeneratorBasicTree(1, false, 4, 7, BlockBOPLog.paging.getVariantState(BOPWoods.JACARANDA), BlockBOPLeaves.paging.getVariantState(BOPTrees.JACARANDA))); + treeGenerator.add("oak", 1, new GeneratorBigTree(1, false, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState())); this.addGenerator("trees", GeneratorStage.TREE, treeGenerator); GeneratorWeighted grassGenerator = new GeneratorWeighted(20); - grassGenerator.add(1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.WHEATGRASS))); - grassGenerator.add(3, new GeneratorGrass(1, Blocks.tallgrass.getDefaultState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.GRASS))); + grassGenerator.add("wheatgrass", 1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.WHEATGRASS))); + grassGenerator.add("tallgrass", 3, new GeneratorGrass(1, Blocks.tallgrass.getDefaultState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.GRASS))); this.addGenerator("grass", GeneratorStage.GRASS, grassGenerator); this.addGenerator("peridot", GeneratorStage.SAND, new GeneratorOreSingle(BOPBlocks.gem_ore.getDefaultState().withProperty(BlockGem.VARIANT, BOPGems.PERIDOT), 12, 4, 32)); diff --git a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenOriginValley.java b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenOriginValley.java index c01b948bb..83dcec39b 100644 --- a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenOriginValley.java +++ b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenOriginValley.java @@ -43,8 +43,8 @@ public class BiomeGenOriginValley extends BOPBiome this.addGenerator("trees", GeneratorStage.TREE, treeGenerator); GeneratorWeighted flowerGenerator = new GeneratorWeighted(4); - flowerGenerator.add(8, new GeneratorFlora(1, BlockBOPFlower.paging.getVariantState(BOPFlowers.ROSE))); - flowerGenerator.add(10, new GeneratorFlora(1, Blocks.yellow_flower.getDefaultState())); + flowerGenerator.add("rose", 8, new GeneratorFlora(1, BlockBOPFlower.paging.getVariantState(BOPFlowers.ROSE))); + flowerGenerator.add("yellow_flower", 10, new GeneratorFlora(1, Blocks.yellow_flower.getDefaultState())); this.addGenerator("flowers", GeneratorStage.FLOWERS, flowerGenerator); } diff --git a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenShrubland.java b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenShrubland.java index 6cd672766..f582b3393 100644 --- a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenShrubland.java +++ b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenShrubland.java @@ -53,11 +53,11 @@ public class BiomeGenShrubland extends BOPBiome this.addGenerator("flowers", GeneratorStage.FLOWERS, new GeneratorFlora(5, Blocks.red_flower.getDefaultState().withProperty(Blocks.red_flower.getTypeProperty(), EnumFlowerType.ALLIUM))); GeneratorWeighted grassGenerator = new GeneratorWeighted(1); - grassGenerator.add(1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.SHORTGRASS))); - grassGenerator.add(1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.MEDIUMGRASS))); - grassGenerator.add(1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.WHEATGRASS))); - grassGenerator.add(1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.DAMPGRASS))); - grassGenerator.add(1, new GeneratorGrass(2, Blocks.tallgrass.getDefaultState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.GRASS))); + grassGenerator.add("shortgrass", 1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.SHORTGRASS))); + grassGenerator.add("mediumgrass", 1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.MEDIUMGRASS))); + grassGenerator.add("wheatgrass", 1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.WHEATGRASS))); + grassGenerator.add("dampgrass", 1, new GeneratorGrass(1, BlockBOPPlant.paging.getVariantState(BOPPlants.DAMPGRASS))); + grassGenerator.add("tallgrass", 1, new GeneratorGrass(2, Blocks.tallgrass.getDefaultState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.GRASS))); this.addGenerator("grass", GeneratorStage.GRASS, grassGenerator); this.addGenerator("peridot", GeneratorStage.SAND, new GeneratorOreSingle(BOPBlocks.gem_ore.getDefaultState().withProperty(BlockGem.VARIANT, BOPGems.PERIDOT), 12, 4, 32)); diff --git a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenThicket.java b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenThicket.java index 3d2bf9662..169e8c801 100644 --- a/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenThicket.java +++ b/src/main/java/biomesoplenty/common/biome/overworld/BiomeGenThicket.java @@ -38,8 +38,8 @@ public class BiomeGenThicket extends BOPBiome this.addWeight(BiomeType.COOL, 5); GeneratorWeighted treeGenerator = new GeneratorWeighted(17); - treeGenerator.add(1, new GeneratorBasicTree(1, false, 4, 7, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState())); - treeGenerator.add(4, new GeneratorBush(1, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState())); + treeGenerator.add("oak", 1, new GeneratorBasicTree(1, false, 4, 7, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState())); + treeGenerator.add("oak_bush", 4, new GeneratorBush(1, Blocks.log.getDefaultState(), Blocks.leaves.getDefaultState())); this.addGenerator("trees", GeneratorStage.TREE, treeGenerator); this.addGenerator("gravel", GeneratorStage.SAND_PASS2, new GeneratorWaterside(6, 7, Blocks.gravel.getDefaultState())); diff --git a/src/main/java/biomesoplenty/common/init/ModGenerators.java b/src/main/java/biomesoplenty/common/init/ModGenerators.java index 56bf3f6c1..c04279db3 100644 --- a/src/main/java/biomesoplenty/common/init/ModGenerators.java +++ b/src/main/java/biomesoplenty/common/init/ModGenerators.java @@ -10,16 +10,8 @@ package biomesoplenty.common.init; import static biomesoplenty.api.biome.generation.GeneratorRegistry.registerGenerator; import biomesoplenty.api.biome.generation.GeneratorWeighted; -import biomesoplenty.api.biome.generation.GeneratorWeightedEntry; -import biomesoplenty.common.world.feature.GeneratorDoubleFlora; -import biomesoplenty.common.world.feature.GeneratorFlora; -import biomesoplenty.common.world.feature.GeneratorGrass; -import biomesoplenty.common.world.feature.GeneratorOreCluster; -import biomesoplenty.common.world.feature.GeneratorOreSingle; -import biomesoplenty.common.world.feature.GeneratorWaterside; -import biomesoplenty.common.world.feature.tree.GeneratorBasicTree; -import biomesoplenty.common.world.feature.tree.GeneratorBigTree; -import biomesoplenty.common.world.feature.tree.GeneratorBush; +import biomesoplenty.common.world.feature.*; +import biomesoplenty.common.world.feature.tree.*; public class ModGenerators { @@ -28,7 +20,6 @@ public class ModGenerators registerGenerator("ore_single", GeneratorOreSingle.class); registerGenerator("ore_cluster", GeneratorOreCluster.class); registerGenerator("weighted", GeneratorWeighted.class); - registerGenerator("weighted_entry", GeneratorWeightedEntry.class); registerGenerator("basic_tree", GeneratorBasicTree.class); registerGenerator("big_tree", GeneratorBigTree.class); registerGenerator("bush", GeneratorBush.class);