Simplify weighted generators and make them easier to configure

This commit is contained in:
Cheeserolls 2015-05-26 10:10:20 +01:00
parent e269c43e54
commit e4e8582eac
9 changed files with 119 additions and 155 deletions

View file

@ -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<GeneratorWeightedEntry> weightedEntries = new ArrayList<GeneratorWeightedEntry>();
public GeneratorWeighted() {}
private HashMap<String, IGenerator> generators = new HashMap<String, IGenerator>();
private HashMap<IGenerator, Integer> weights = new HashMap<IGenerator, Integer>();
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<IGenerator, Integer> 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<WrappedJsonObject> 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<String,Generator> kind of arrangement
// Then they could be individually altered
}
}

View file

@ -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<? extends IGenerator>)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;
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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()));

View file

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