Biome API, Bonemeal API

This commit is contained in:
paulevsGitch 2021-05-24 20:30:48 +03:00
parent 67c9c2302d
commit 9d25e0b361
10 changed files with 682 additions and 117 deletions

View file

@ -0,0 +1,153 @@
package ru.bclib.api;
import java.util.HashMap;
import java.util.Random;
import com.google.common.collect.Maps;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.impl.biome.InternalBiomeData;
import net.minecraft.client.Minecraft;
import net.minecraft.core.Registry;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.Biome.ClimateParameters;
import net.minecraft.world.level.biome.Biomes;
import ru.bclib.util.MHelper;
import ru.bclib.world.biomes.BCLBiome;
public class BiomeAPI {
/**
* Empty biome used as default value if requested biome doesn't exist or linked. Shouldn't be registered anywhere to prevent bugs.
* Have {@code Biomes.THE_VOID} as the reference biome.
*/
public static final BCLBiome EMPTY_BIOME = new BCLBiome(Biomes.THE_VOID.location(), BuiltinRegistries.BIOME.get(Biomes.THE_VOID), 0, 0);
private static final HashMap<ResourceLocation, BCLBiome> ID_MAP = Maps.newHashMap();
private static final HashMap<Biome, BCLBiome> CLIENT = Maps.newHashMap();
private static Registry<Biome> biomeRegistry;
/**
* Initialize registry if it was not initialized in world generation (when using mods/datapacks, that overrides the End generation)
* @param server - {@link MinecraftServer}
*/
public static void initRegistry(MinecraftServer server) {
if (biomeRegistry == null || biomeRegistry == BuiltinRegistries.BIOME) {
biomeRegistry = server.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
}
}
public static void registerBiomeDirectly(BCLBiome biome) {
Registry.register(BuiltinRegistries.BIOME, biome.getID(), biome.getBiome());
}
/**
* Adds {@link BCLBiome} to FabricAPI biomes as the Nether biome (with random {@link ClimateParameters}).
* @param biome - {@link BCLBiome}.
*/
public static void addNetherBiomeToFabricApi(BCLBiome biome) {
ResourceKey<Biome> key = BuiltinRegistries.BIOME.getResourceKey(biome.getBiome()).get();
Random random = new Random(biome.getID().toString().hashCode());
ClimateParameters parameters = new ClimateParameters(
MHelper.randRange(-2F, 2F, random),
MHelper.randRange(-2F, 2F, random),
MHelper.randRange(-2F, 2F, random),
MHelper.randRange(-2F, 2F, random),
MHelper.randRange(-2F, 2F, random)
);
InternalBiomeData.addNetherBiome(key, parameters);
}
/**
* Adds {@link BCLBiome} to FabricAPI biomes as an End land biome (generating on islands).
* @param biome - {@link BCLBiome}.
*/
public static void addEndLandBiomeToFabricApi(BCLBiome biome) {
float weight = biome.getGenChance();
ResourceKey<Biome> key = BuiltinRegistries.BIOME.getResourceKey(biome.getBiome()).get();
InternalBiomeData.addEndBiomeReplacement(Biomes.END_HIGHLANDS, key, weight);
InternalBiomeData.addEndBiomeReplacement(Biomes.END_MIDLANDS, key, weight);
}
/**
* Adds {@link BCLBiome} to FabricAPI biomes as an End void biome (generating between islands in the void).
* @param biome - {@link BCLBiome}.
*/
public static void addEndVoidBiomeToFabricApi(BCLBiome biome) {
float weight = biome.getGenChance();
ResourceKey<Biome> key = BuiltinRegistries.BIOME.getResourceKey(biome.getBiome()).get();
InternalBiomeData.addEndBiomeReplacement(Biomes.SMALL_END_ISLANDS, key, weight);
}
/**
* Get {@link BCLBiome} from {@link Biome} instance on server. Used to convert world biomes to BCLBiomes.
* @param biome - {@link Biome} from world.
* @return {@link BCLBiome} or {@code BiomeAPI.EMPTY_BIOME}.
*/
public static BCLBiome getFromBiome(Biome biome) {
return ID_MAP.getOrDefault(biomeRegistry.getKey(biome), EMPTY_BIOME);
}
/**
* Get {@link BCLBiome} from biome on client. Used in fog rendering.
* @param biome - {@link Biome} from client world.
* @return {@link BCLBiome} or {@code BiomeAPI.EMPTY_BIOME}.
*/
@Environment(EnvType.CLIENT)
public static BCLBiome getRenderBiome(Biome biome) {
BCLBiome endBiome = CLIENT.get(biome);
if (endBiome == null) {
Minecraft minecraft = Minecraft.getInstance();
ResourceLocation id = minecraft.level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getKey(biome);
endBiome = id == null ? EMPTY_BIOME : ID_MAP.getOrDefault(id, EMPTY_BIOME);
CLIENT.put(biome, endBiome);
}
return endBiome;
}
/**
* Get biome {@link ResourceLocation} from given {@link Biome}.
* @param biome - {@link Biome} from server world.
* @return biome {@link ResourceLocation}.
*/
public static ResourceLocation getBiomeID(Biome biome) {
ResourceLocation id = biomeRegistry.getKey(biome);
return id == null ? EMPTY_BIOME.getID() : id;
}
/**
* Get {@link BCLBiome} from given {@link ResourceLocation}.
* @param biomeID - biome {@link ResourceLocation}.
* @return {@link BCLBiome} or {@code BiomeAPI.EMPTY_BIOME}.
*/
public static BCLBiome getBiome(ResourceLocation biomeID) {
return ID_MAP.getOrDefault(biomeID, EMPTY_BIOME);
}
/**
* Get actual {@link Biome} from given {@link BCLBiome}. If it is null it will request it from current {@link Registry}.
* @param biome - {@link BCLBiome}.
* @return {@link Biome}.
*/
public static Biome getActualBiome(BCLBiome biome) {
Biome actual = biome.getActualBiome();
if (actual == null) {
biome.updateActualBiomes(biomeRegistry);
actual = biome.getActualBiome();
}
return actual;
}
/**
* Check if biome with {@link ResourceLocation} exists in API registry.
* @param biomeID - biome {@link ResourceLocation}.
* @return
*/
public static boolean hasBiome(ResourceLocation biomeID) {
return ID_MAP.containsKey(biomeID);
}
}

View file

@ -0,0 +1,120 @@
package ru.bclib.api;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import ru.bclib.util.WeightedList;
public class BonemealAPI {
private static final Map<ResourceLocation, Map<Block, WeightedList<Block>>> WATER_GRASS_BIOMES = Maps.newHashMap();
private static final Map<ResourceLocation, Map<Block, WeightedList<Block>>> LAND_GRASS_BIOMES = Maps.newHashMap();
private static final Map<Block, WeightedList<Block>> WATER_GRASS_TYPES = Maps.newHashMap();
private static final Map<Block, WeightedList<Block>> LAND_GRASS_TYPES = Maps.newHashMap();
private static final Set<Block> SPREADABLE_BLOCKS = Sets.newHashSet();
public static void addSpreadableBlock(Block block) {
SPREADABLE_BLOCKS.add(block);
}
public static boolean isSpreadable(Block block) {
return SPREADABLE_BLOCKS.contains(block);
}
public static void addLandGrass(Block terrain, Block plant) {
addLandGrass(terrain, plant, 1F);
}
public static void addLandGrass(ResourceLocation biome, Block terrain, Block plant) {
addLandGrass(biome, terrain, plant, 1F);
}
public static void addLandGrass(Block terrain, Block plant, float chance) {
WeightedList<Block> list = LAND_GRASS_TYPES.get(terrain);
if (list == null) {
list = new WeightedList<Block>();
LAND_GRASS_TYPES.put(terrain, list);
}
list.add(plant, chance);
}
public static void addLandGrass(ResourceLocation biome, Block terrain, Block plant, float chance) {
Map<Block, WeightedList<Block>> map = LAND_GRASS_BIOMES.get(biome);
if (map == null) {
map = Maps.newHashMap();
LAND_GRASS_BIOMES.put(biome, map);
}
WeightedList<Block> list = map.get(terrain);
if (list == null) {
list = new WeightedList<Block>();
map.put(terrain, list);
}
list.add(plant, chance);
}
public static void addWaterGrass(Block terrain, Block plant) {
addWaterGrass(terrain, plant, 1F);
}
public static void addWaterGrass(ResourceLocation biome, Block terrain, Block plant) {
addWaterGrass(biome, terrain, plant, 1F);
}
public static void addWaterGrass(Block terrain, Block plant, float chance) {
WeightedList<Block> list = WATER_GRASS_TYPES.get(terrain);
if (list == null) {
list = new WeightedList<Block>();
WATER_GRASS_TYPES.put(terrain, list);
}
list.add(plant, chance);
}
public static void addWaterGrass(ResourceLocation biome, Block terrain, Block plant, float chance) {
Map<Block, WeightedList<Block>> map = WATER_GRASS_BIOMES.get(biome);
if (map == null) {
map = Maps.newHashMap();
WATER_GRASS_BIOMES.put(biome, map);
}
WeightedList<Block> list = map.get(terrain);
if (list == null) {
list = new WeightedList<Block>();
map.put(terrain, list);
}
list.add(plant, chance);
}
public static Block getLandGrass(ResourceLocation biomeID, Block terrain, Random random) {
Map<Block, WeightedList<Block>> map = LAND_GRASS_BIOMES.get(biomeID);
WeightedList<Block> list = null;
if (map != null) {
list = map.get(terrain);
if (list == null) {
list = LAND_GRASS_TYPES.get(terrain);
}
}
else {
list = LAND_GRASS_TYPES.get(terrain);
}
return list == null ? null : list.get(random);
}
public static Block getWaterGrass(ResourceLocation biomeID, Block terrain, Random random) {
Map<Block, WeightedList<Block>> map = LAND_GRASS_BIOMES.get(biomeID);
WeightedList<Block> list = null;
if (map != null) {
list = map.get(terrain);
if (list == null) {
list = LAND_GRASS_TYPES.get(terrain);
}
}
else {
list = LAND_GRASS_TYPES.get(terrain);
}
return list == null ? null : list.get(random);
}
}

View file

@ -1,20 +0,0 @@
package ru.bclib.api;
import net.minecraft.core.Registry;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilder;
import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilderBaseConfiguration;
public class SurfaceBuilders {
public static SurfaceBuilder<SurfaceBuilderBaseConfiguration> register(String name, SurfaceBuilder<SurfaceBuilderBaseConfiguration> builder) {
return Registry.register(Registry.SURFACE_BUILDER, name, builder);
}
public static SurfaceBuilderBaseConfiguration makeSimpleConfig(Block block) {
BlockState state = block.defaultBlockState();
return new SurfaceBuilderBaseConfiguration(state, state, state);
}
public static void register() {}
}