Changed management of actualBiome

This commit is contained in:
Frank 2022-05-17 00:32:41 +02:00
parent 38b8883b6a
commit 45b014cd3c
17 changed files with 223 additions and 275 deletions

View file

@ -18,6 +18,7 @@ import net.minecraft.data.BuiltinRegistries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.BiomeTags;
import net.minecraft.util.random.WeightedRandomList;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
@ -49,6 +50,7 @@ import net.minecraft.world.level.levelgen.placement.PlacedFeature;
import org.apache.commons.lang3.mutable.MutableInt;
import org.jetbrains.annotations.Nullable;
import ru.bclib.BCLib;
import ru.bclib.api.tag.TagAPI;
import ru.bclib.entity.BCLEntityWrapper;
import ru.bclib.interfaces.BiomeSourceAccessor;
import ru.bclib.interfaces.NoiseGeneratorSettingsProvider;
@ -86,13 +88,9 @@ public class BiomeAPI {
*/
public static final BCLBiome EMPTY_BIOME = new BCLBiome(Biomes.THE_VOID.location());
public static final BiomePicker NETHER_BIOME_PICKER = new BiomePicker();
public static final BiomePicker END_LAND_BIOME_PICKER = new BiomePicker();
public static final BiomePicker END_VOID_BIOME_PICKER = new BiomePicker();
private static final Map<ResourceLocation, BCLBiome> ID_MAP = Maps.newHashMap();
private static final Map<Biome, BCLBiome> CLIENT = Maps.newHashMap();
private static Registry<Biome> biomeRegistry;
public static Registry<Biome> biomeRegistry;
private static final Map<Holder<PlacedFeature>, Integer> FEATURE_ORDER = Maps.newHashMap();
private static final MutableInt FEATURE_ORDER_ID = new MutableInt(0);
@ -169,6 +167,7 @@ public class BiomeAPI {
Registry.register(BuiltinRegistries.BIOME, loc, biome);
}
ID_MAP.put(bclbiome.getID(), bclbiome);
bclbiome.afterRegistration();
return bclbiome;
}
@ -186,16 +185,16 @@ public class BiomeAPI {
/**
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
* After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API.
* @param biome {@link BCLBiome}
* @param bclBiome {@link BCLBiome}
* @return {@link BCLBiome}
*/
public static BCLBiome registerNetherBiome(BCLBiome biome) {
registerBiome(biome);
NETHER_BIOME_PICKER.addBiome(biome);
ResourceKey<Biome> key = BiomeAPI.getBiomeKeyOrThrow(biome.getBiomeHolder());
public static BCLBiome registerNetherBiome(BCLBiome bclBiome) {
registerBiome(bclBiome);
biome.forEachClimateParameter(p -> NetherBiomeData.addNetherBiome(key, p));
return biome;
ResourceKey<Biome> key = BiomeAPI.getBiomeKeyOrThrow(bclBiome.getBiomeHolder());
bclBiome.forEachClimateParameter(p -> NetherBiomeData.addNetherBiome(key, p));
TagAPI.addBiomeTag(BiomeTags.IS_NETHER, bclBiome.getBiome());
return bclBiome;
}
/**
@ -206,9 +205,8 @@ public class BiomeAPI {
*/
public static BCLBiome registerNetherBiome(Biome biome) {
BCLBiome bclBiome = new BCLBiome(biome, null);
NETHER_BIOME_PICKER.addBiome(bclBiome);
registerBiome(bclBiome);
TagAPI.addBiomeTag(BiomeTags.IS_NETHER, bclBiome.getBiome());
return bclBiome;
}
@ -221,7 +219,6 @@ public class BiomeAPI {
public static BCLBiome registerEndLandBiome(BCLBiome biome) {
registerBiome(biome);
END_LAND_BIOME_PICKER.addBiome(biome);
float weight = biome.getGenChance();
ResourceKey<Biome> key = BiomeAPI.getBiomeKey(biome.getBiome());
TheEndBiomeData.addEndBiomeReplacement(Biomes.END_HIGHLANDS, key, weight);
@ -238,7 +235,6 @@ public class BiomeAPI {
public static BCLBiome registerEndLandBiome(Holder<Biome> biome) {
BCLBiome bclBiome = new BCLBiome(biome.value(), null);
END_LAND_BIOME_PICKER.addBiome(bclBiome);
registerBiome(bclBiome);
return bclBiome;
}
@ -253,7 +249,6 @@ public class BiomeAPI {
public static BCLBiome registerEndLandBiome(Holder<Biome> biome, float genChance) {
BCLBiome bclBiome = new BCLBiome(biome.value(), VanillaBiomeSettings.createVanilla().setGenChance(genChance).build());
END_LAND_BIOME_PICKER.addBiome(bclBiome);
registerBiome(bclBiome);
return bclBiome;
}
@ -267,7 +262,6 @@ public class BiomeAPI {
public static BCLBiome registerEndVoidBiome(BCLBiome biome) {
registerBiome(biome);
END_VOID_BIOME_PICKER.addBiome(biome);
float weight = biome.getGenChance();
ResourceKey<Biome> key = BiomeAPI.getBiomeKeyOrThrow(biome.getBiomeHolder());
TheEndBiomeData.addEndBiomeReplacement(Biomes.SMALL_END_ISLANDS, key, weight);
@ -283,7 +277,6 @@ public class BiomeAPI {
public static BCLBiome registerEndVoidBiome(Holder<Biome> biome) {
BCLBiome bclBiome = new BCLBiome(biome.value(), null);
END_VOID_BIOME_PICKER.addBiome(bclBiome);
registerBiome(bclBiome);
return bclBiome;
}
@ -298,7 +291,6 @@ public class BiomeAPI {
public static BCLBiome registerEndVoidBiome(Holder<Biome> biome, float genChance) {
BCLBiome bclBiome = new BCLBiome(biome.value(), VanillaBiomeSettings.createVanilla().setGenChance(genChance).build());
END_VOID_BIOME_PICKER.addBiome(bclBiome);
registerBiome(bclBiome);
return bclBiome;
}
@ -451,18 +443,6 @@ public class BiomeAPI {
return getFromRegistry(biomeID) == null;
}
public static boolean isNetherBiome(ResourceLocation biomeID) {
return pickerHasBiome(NETHER_BIOME_PICKER, biomeID);
}
public static boolean isEndBiome(ResourceLocation biomeID) {
return pickerHasBiome(END_LAND_BIOME_PICKER, biomeID) || pickerHasBiome(END_VOID_BIOME_PICKER, biomeID);
}
private static boolean pickerHasBiome(BiomePicker picker, ResourceLocation key) {
return picker.getBiomes().stream().filter(biome -> biome.getID().equals(key)).findFirst().isPresent();
}
/**
* Registers new biome modification for specified dimension. Will work both for mod and datapack biomes.
* @param dimensionID {@link ResourceLocation} dimension ID, example: Level.OVERWORLD or "minecraft:overworld".

View file

@ -33,5 +33,6 @@ public class Configs {
BIOMES_CONFIG.keeper.registerEntry(new ConfigKey("end_land_biomes", "force_include"), new StringArrayEntry(Collections.EMPTY_LIST));
BIOMES_CONFIG.keeper.registerEntry(new ConfigKey("end_void_biomes", "force_include"), new StringArrayEntry(Collections.EMPTY_LIST));
BIOMES_CONFIG.keeper.registerEntry(new ConfigKey("nether_biomes", "force_include"), new StringArrayEntry(Collections.EMPTY_LIST));
BIOMES_CONFIG.keeper.registerEntry(new ConfigKey("nether_biomes", "force_exclude"), new StringArrayEntry(Collections.EMPTY_LIST));
}
}

View file

@ -1,9 +1,10 @@
package ru.bclib.interfaces;
import ru.bclib.world.biomes.BCLBiome;
import ru.bclib.world.generator.BiomePicker;
public interface BiomeChunk {
void setBiome(int x, int z, BCLBiome biome);
BCLBiome getBiome(int x, int z);
void setBiome(int x, int z, BiomePicker.Entry biome);
BiomePicker.Entry getBiome(int x, int z);
int getSide();
}

View file

@ -1,10 +1,11 @@
package ru.bclib.interfaces;
import ru.bclib.world.biomes.BCLBiome;
import ru.bclib.world.generator.BiomePicker;
public interface BiomeMap {
void setChunkProcessor(TriConsumer<Integer, Integer, Integer> processor);
BiomeChunk getChunk(int cx, int cz, boolean update);
BCLBiome getBiome(double x, double y, double z);
BiomePicker.Entry getBiome(double x, double y, double z);
void clearCache();
}

View file

@ -0,0 +1,9 @@
package ru.bclib.mixin.common;
import net.minecraft.world.level.biome.Biome;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(Biome.class)
public class BiomeMixin {
}

View file

@ -25,6 +25,7 @@ import java.util.Random;import net.minecraft.util.RandomSource;
import net.minecraft.world.level.levelgen.WorldgenRandom;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
public class BCLBiome extends BCLBiomeSettings {
@ -38,7 +39,6 @@ public class BCLBiome extends BCLBiomeSettings {
private Consumer<Holder<Biome>> surfaceInit;
private BCLBiome biomeParent;
private Holder<Biome> actualBiome;
/**
* Create wrapper for existing biome using its {@link ResourceLocation} identifier.
@ -143,6 +143,11 @@ public class BCLBiome extends BCLBiomeSettings {
return subbiomes.get(random);
}
public void forEachSubBiome(BiConsumer<BCLBiome, Float> consumer){
for (int i=0; i<subbiomes.size();i++)
consumer.accept(subbiomes.get(i), subbiomes.getWeight(i));
}
/**
* Getter for parent {@link BCLBiome} or null if there are no parent biome.
* @return {@link BCLBiome} or null.
@ -181,42 +186,43 @@ public class BCLBiome extends BCLBiomeSettings {
return biome;
}
/**
* Getter for actual biome (biome from current world registry with same {@link ResourceLocation} id).
* @return {@link Biome}.
*/
public Holder<Biome> getActualBiome() {
return this.actualBiome;
}
// /**
// * Recursively update biomes to correct world biome registry instances, for internal usage only.
// * @param biomeRegistry {@link Registry} for {@link Biome}.
// */
// public void updateActualBiomes(Registry<Biome> biomeRegistry) {
// subbiomes.forEach((sub) -> {
// if (sub != this) {
// sub.updateActualBiomes(biomeRegistry);
// }
// });
// if (edge != null && edge != this) {
// edge.updateActualBiomes(biomeRegistry);
// }
//
// final ResourceKey<Biome> key = biomeRegistry.getResourceKey(biomeRegistry.get(biomeID)).orElseThrow();
// Holder<Biome> aBiome = biomeRegistry.getOrCreateHolder(key);
// if (aBiome != actualBiome && actualBiome != null) {
// System.out.println("Changed actual Biome");
// }
// this.actualBiome = aBiome;
// if (actualBiome == null) {
// BCLib.LOGGER.error("Unable to find actual Biome for " + biomeID);
// }
// }
/**
* Recursively update biomes to correct world biome registry instances, for internal usage only.
* @param biomeRegistry {@link Registry} for {@link Biome}.
* For internal use from BiomeAPI only
*/
public void updateActualBiomes(Registry<Biome> biomeRegistry) {
subbiomes.forEach((sub) -> {
if (sub != this) {
sub.updateActualBiomes(biomeRegistry);
}
});
if (edge != null && edge != this) {
edge.updateActualBiomes(biomeRegistry);
}
final ResourceKey<Biome> key = biomeRegistry.getResourceKey(biomeRegistry.get(biomeID)).orElseThrow();
this.actualBiome = biomeRegistry.getOrCreateHolder(key);
if (actualBiome==null) {
BCLib.LOGGER.error("Unable to find actual Biome for " + biomeID);
}
public void afterRegistration(){
if (!this.structureTags.isEmpty()) {
structureTags.forEach(tagKey -> TagAPI.addBiomeTag(tagKey, actualBiome.value()));
structureTags.forEach(tagKey ->
TagAPI.addBiomeTag(tagKey, biome)
);
}
if (this.surfaceInit != null) {
surfaceInit.accept(actualBiome);
surfaceInit.accept(getBiomeHolder());
}
}
@ -229,6 +235,7 @@ public class BCLBiome extends BCLBiomeSettings {
*/
@Nullable
@SuppressWarnings("unchecked")
@Deprecated(forRemoval = true)
public <T> T getCustomData(String name) {
return (T) customData.get(name);
}
@ -240,6 +247,7 @@ public class BCLBiome extends BCLBiomeSettings {
* @return object value or default value.
*/
@SuppressWarnings("unchecked")
@Deprecated(forRemoval = true)
public <T> T getCustomData(String name, T defaultValue) {
return (T) customData.getOrDefault(name, defaultValue);
}
@ -309,8 +317,8 @@ public class BCLBiome extends BCLBiomeSettings {
* @param surface {@link SurfaceRules.RuleSource} rule.
*/
public void setSurface(RuleSource surface) {
this.surfaceInit = (actualBiome) -> {
ResourceKey key = BiomeAPI.getBiomeKey(actualBiome);
this.surfaceInit = (b) -> {
final ResourceKey key = BiomeAPI.getBiomeKey(b);
if (key == null) {
BCLib.LOGGER.warning("BCL Biome " + biomeID + " does not have registry key!");
}
@ -331,62 +339,4 @@ public class BCLBiome extends BCLBiomeSettings {
}
private boolean didLoadConfig = false;
// /**
// * Set gen chance for this biome, default value is 1.0.
// * @param genChance chance of this biome to be generated.
// * @return same {@link BCLBiome}.
// */
// public BCLBiome setGenChance(float genChance) {
// super.setGenChance(genChance);
// return this;
// }
//
// /**
// * Setter for terrain height, can be used in custom terrain generator.
// * @param terrainHeight a relative float terrain height value.
// * @return same {@link BCLBiome}.
// */
// public BCLBiome setTerrainHeight(float terrainHeight) {
// super.setTerrainHeight(genChance);
// return this;
// }
//
// /**
// * Set biome vertical distribution (for tall Nether only).
// * @return same {@link BCLBiome}.
// */
// public BCLBiome setVertical() {
// return setVertical(true);
// }
//
// /**
// * Set biome vertical distribution (for tall Nether only).
// * @param vertical {@code boolean} value.
// * @return same {@link BCLBiome}.
// */
// public BCLBiome setVertical(boolean vertical) {
// super.setVertical(vertical);
// return this;
// }
//
// /**
// * Sets fog density for this biome.
// * @param fogDensity
// * @return same {@link BCLBiome}.
// */
// public BCLBiome setFogDensity(float fogDensity) {
// super.setFogDensity(fogDensity);
// return this;
// }
//
// /**
// * Set edges size for this biome. Size is in blocks.
// * @param size as a float value.
// * @return same {@link BCLBiome}.
// */
// public BCLBiome setEdgeSize(int size) {
// edgeSize = size;
// return this;
// }
}

View file

@ -19,7 +19,7 @@ public abstract class BCLBiomeSource extends BiomeSource {
protected BCLBiomeSource(Registry<Biome> biomeRegistry, List<Holder<Biome>> list) {
super(preInit(biomeRegistry, list));
System.out.println(this + " with Registry: "+biomeRegistry);
System.out.println(this + " with Registry: "+ biomeRegistry.getClass().getName() + "@" + Integer.toHexString(biomeRegistry.hashCode()));
this.biomeRegistry = biomeRegistry;
BiomeAPI.initRegistry(biomeRegistry);

View file

@ -54,6 +54,8 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
private BiomeMap mapLand;
private BiomeMap mapVoid;
private final BiomePicker endLandBiomePicker;
private final BiomePicker endVoidBiomePicker;
public BCLibEndBiomeSource(Registry<Biome> biomeRegistry, long seed) {
this(biomeRegistry);
@ -63,8 +65,8 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
public BCLibEndBiomeSource(Registry<Biome> biomeRegistry) {
super(biomeRegistry, getBiomes(biomeRegistry));
BiomeAPI.END_LAND_BIOME_PICKER.clearMutables();
BiomeAPI.END_VOID_BIOME_PICKER.clearMutables();
endLandBiomePicker = new BiomePicker(biomeRegistry);
endVoidBiomePicker = new BiomePicker(biomeRegistry);
List<String> includeVoid = Configs.BIOMES_CONFIG.getEntry("force_include",
"end_void_biomes",
@ -77,33 +79,25 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
BCLBiome bclBiome = new BCLBiome(key, biome.value());
if (includeVoid.contains(key.toString())) {
BiomeAPI.END_VOID_BIOME_PICKER.addBiomeMutable(bclBiome);
endVoidBiomePicker.addBiome(bclBiome);
} else {
BiomeAPI.END_LAND_BIOME_PICKER.addBiomeMutable(bclBiome);
endLandBiomePicker.addBiome(bclBiome);
}
} else {
BCLBiome bclBiome = BiomeAPI.getBiome(key);
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
if (bclBiome.getParentBiome() == null) {
if (!BiomeAPI.END_LAND_BIOME_PICKER.containsImmutable(key) && !BiomeAPI.END_VOID_BIOME_PICKER.containsImmutable(
key)) {
if (includeVoid.contains(key.toString())) {
BiomeAPI.END_VOID_BIOME_PICKER.addBiomeMutable(bclBiome);
endVoidBiomePicker.addBiome(bclBiome);
} else {
BiomeAPI.END_LAND_BIOME_PICKER.addBiomeMutable(bclBiome);
}
endLandBiomePicker.addBiome(bclBiome);
}
}
}
}
});
BiomeAPI.END_LAND_BIOME_PICKER.getBiomes().forEach(biome -> biome.updateActualBiomes(biomeRegistry));
BiomeAPI.END_VOID_BIOME_PICKER.getBiomes().forEach(biome -> biome.updateActualBiomes(biomeRegistry));
BiomeAPI.END_LAND_BIOME_PICKER.rebuild();
BiomeAPI.END_VOID_BIOME_PICKER.rebuild();
this.centerBiome = biomeRegistry.getOrCreateHolder(Biomes.THE_END);
this.barrens = biomeRegistry.getOrCreateHolder(Biomes.END_BARRENS);
@ -143,8 +137,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
}
key = bclBiome.getID();
}
return BiomeAPI.END_LAND_BIOME_PICKER.containsImmutable(key) || BiomeAPI.END_VOID_BIOME_PICKER.containsImmutable(
key) || (isEndBiome && BiomeAPI.isDatapackBiome(key));
return isEndBiome;
}).toList();
}
@ -179,17 +172,17 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
if (GeneratorOptions.useOldBiomeGenerator()) {
this.mapLand = new SquareBiomeMap(seed,
GeneratorOptions.getBiomeSizeEndLand(),
BiomeAPI.END_LAND_BIOME_PICKER);
endLandBiomePicker);
this.mapVoid = new SquareBiomeMap(seed,
GeneratorOptions.getBiomeSizeEndVoid(),
BiomeAPI.END_VOID_BIOME_PICKER);
endVoidBiomePicker);
} else {
this.mapLand = new HexBiomeMap(seed,
GeneratorOptions.getBiomeSizeEndLand(),
BiomeAPI.END_LAND_BIOME_PICKER);
endLandBiomePicker);
this.mapVoid = new HexBiomeMap(seed,
GeneratorOptions.getBiomeSizeEndVoid(),
BiomeAPI.END_VOID_BIOME_PICKER);
endVoidBiomePicker);
}
WorldgenRandom chunkRandom = new WorldgenRandom(new LegacyRandomSource(seed));
@ -230,16 +223,16 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
}
if (height < -10F) {
return mapVoid.getBiome(posX, biomeY << 2, posZ).getActualBiome();
return mapVoid.getBiome(posX, biomeY << 2, posZ).actual;
} else {
return mapLand.getBiome(posX, biomeY << 2, posZ).getActualBiome();
return mapLand.getBiome(posX, biomeY << 2, posZ).actual;
}
} else {
pos.setLocation(biomeX, biomeZ);
if (endLandFunction.apply(pos)) {
return dist <= farEndBiomes ? centerBiome : mapLand.getBiome(posX, biomeY << 2, posZ).getActualBiome();
return dist <= farEndBiomes ? centerBiome : mapLand.getBiome(posX, biomeY << 2, posZ).actual;
} else {
return dist <= farEndBiomes ? barrens : mapVoid.getBiome(posX, biomeY << 2, posZ).getActualBiome();
return dist <= farEndBiomes ? barrens : mapVoid.getBiome(posX, biomeY << 2, posZ).actual;
}
}
}

View file

@ -8,6 +8,8 @@ import net.minecraft.tags.BiomeTags;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.world.level.biome.*;
import net.fabricmc.fabric.impl.biome.NetherBiomeData;
import com.mojang.datafixers.kinds.Applicative;
import com.mojang.datafixers.util.Either;
import com.mojang.datafixers.util.Pair;
@ -48,30 +50,26 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource {
.apply(instance, instance.stable(BCLibNetherBiomeSource::new))
);
private BiomeMap biomeMap;
private final BiomePicker biomePicker;
public BCLibNetherBiomeSource(Registry<Biome> biomeRegistry) {
super(biomeRegistry, getBiomes(biomeRegistry));
BiomeAPI.NETHER_BIOME_PICKER.clearMutables();
biomePicker = new BiomePicker(biomeRegistry);
this.possibleBiomes().forEach(biome -> {
ResourceLocation key = biome.unwrapKey().orElseThrow().location();
if (!BiomeAPI.hasBiome(key)) {
BCLBiome bclBiome = new BCLBiome(key, biome.value());
BiomeAPI.NETHER_BIOME_PICKER.addBiomeMutable(bclBiome);
biomePicker.addBiome(bclBiome);
} else {
BCLBiome bclBiome = BiomeAPI.getBiome(key);
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
if (bclBiome.getParentBiome() == null) {
if (!BiomeAPI.NETHER_BIOME_PICKER.containsImmutable(key)) {
BiomeAPI.NETHER_BIOME_PICKER.addBiomeMutable(bclBiome);
}
biomePicker.addBiome(bclBiome);
}
}
}
});
BiomeAPI.NETHER_BIOME_PICKER.getBiomes().forEach(biome -> biome.updateActualBiomes(biomeRegistry));
BiomeAPI.NETHER_BIOME_PICKER.rebuild();
}
public BCLibNetherBiomeSource(Registry<Biome> biomeRegistry, long seed) {
@ -103,31 +101,19 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource {
private static List<Holder<Biome>> getBiomes(Registry<Biome> biomeRegistry) {
List<String> include = Configs.BIOMES_CONFIG.getEntry("force_include", "nether_biomes", StringArrayEntry.class)
.getValue();
List<String> exclude = Configs.BIOMES_CONFIG.getEntry("force_exclude", "nether_biomes", StringArrayEntry.class)
.getValue();
return biomeRegistry.stream()
.filter(biome -> biomeRegistry.getResourceKey(biome).isPresent())
.map(biome -> biomeRegistry.getOrCreateHolder(biomeRegistry.getResourceKey(biome).get()))
.filter(biome -> {
ResourceLocation key = biome.unwrapKey().orElseThrow().location();
ResourceLocation location = biome.unwrapKey().orElseThrow().location();
final String strLocation = location.toString();
if (exclude.contains(strLocation)) return false;
if (include.contains(strLocation)) return true;
if (include.contains(key.toString())) {
return true;
}
if (GeneratorOptions.addNetherBiomesByTag() && biome.is(BiomeTags.IS_NETHER)) {
return true;
}
BCLBiome bclBiome = BiomeAPI.getBiome(key);
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
if (bclBiome.getParentBiome() != null) {
bclBiome = bclBiome.getParentBiome();
}
key = bclBiome.getID();
}
final boolean isNetherBiome = biome.is(BiomeTags.IS_NETHER);
return BiomeAPI.NETHER_BIOME_PICKER.containsImmutable(key) || (isNetherBiome && BiomeAPI.isDatapackBiome(
key));
return NetherBiomeData.canGenerateInNether(biome.unwrapKey().get()) || biome.is(BiomeTags.IS_NETHER);
}).toList();
}
@ -141,8 +127,8 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource {
@Override
public void setSeed(long seed) {
super.setSeed(seed);
biomePicker.rebuild();
initMap(seed);
}
@ -158,8 +144,8 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource {
if ((biomeX & 63) == 0 && (biomeZ & 63) == 0) {
biomeMap.clearCache();
}
BCLBiome bb = biomeMap.getBiome(biomeX << 2, biomeY << 2, biomeZ << 2);
return bb.getActualBiome();
BiomePicker.Entry bb = biomeMap.getBiome(biomeX << 2, biomeY << 2, biomeZ << 2);
return bb.actual;
}
@Override
@ -176,7 +162,7 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource {
this.biomeMap = new MapStack(
seed,
GeneratorOptions.getBiomeSizeNether(),
BiomeAPI.NETHER_BIOME_PICKER,
biomePicker,
GeneratorOptions.getVerticalBiomeSizeNether(),
worldHeight,
mapConstructor
@ -184,12 +170,12 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource {
} else {
this.biomeMap = mapConstructor.apply(seed,
GeneratorOptions.getBiomeSizeNether(),
BiomeAPI.NETHER_BIOME_PICKER);
biomePicker);
}
}
@Override
public String toString() {
return "BCLib - Nether BiomeSource";
return "BCLib - Nether BiomeSource ("+Integer.toHexString(hashCode())+")";
}
}

View file

@ -2,74 +2,106 @@ package ru.bclib.world.generator;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import ru.bclib.util.WeighTree;
import ru.bclib.util.WeightedList;
import ru.bclib.world.biomes.BCLBiome;
import java.util.List;
import java.util.Random;import net.minecraft.util.RandomSource;
import java.util.*;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.levelgen.WorldgenRandom;
import java.util.Set;
public class BiomePicker {
private final Set<ResourceLocation> immutableIDs = Sets.newHashSet();
private final List<BCLBiome> biomes = Lists.newArrayList();
private WeighTree<BCLBiome> tree;
private int biomeCount = 0;
public final Map<BCLBiome, Entry> all = new HashMap<>();
public class Entry {
public final BCLBiome bclBiome;
public final Holder<Biome> actual;
public final ResourceKey<Biome> key;
private final WeightedList<Entry> subbiomes = new WeightedList<>();
private final Entry edge;
private final Entry parent;
private Entry(BCLBiome bclBiome){
all.put(bclBiome, this);
this.bclBiome = bclBiome;
this.key = biomeRegistry.getResourceKey(biomeRegistry.get(bclBiome.getID())).orElseThrow();
this.actual = biomeRegistry.getOrCreateHolder(key);
bclBiome.forEachSubBiome((b, w)->{
subbiomes.add(create(b), w);
});
edge = bclBiome.getEdge()!=null?create(bclBiome.getEdge()):null;
parent = bclBiome.getParentBiome()!=null?create(bclBiome.getParentBiome()):null;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Entry entry = (Entry) o;
return bclBiome.equals(entry.bclBiome);
}
@Override
public int hashCode() {
return Objects.hash(bclBiome);
}
public Entry getSubBiome(WorldgenRandom random) {
return subbiomes.get(random);
}
public Entry getEdge(){
return edge;
}
public Entry getParentBiome(){
return parent;
}
public boolean isSame(Entry e){
return bclBiome.isSame(e.bclBiome);
}
}
private Entry create(BCLBiome bclBiome){
Entry e = all.get(bclBiome);
if (e!=null) return e;
return new Entry(bclBiome);
}
private final List<Entry> biomes = Lists.newArrayList();
private final Registry<Biome> biomeRegistry;
private WeighTree<Entry> tree;
public BiomePicker(Registry<Biome> biomeRegistry){
this.biomeRegistry = biomeRegistry;
}
public void addBiome(BCLBiome biome) {
if (immutableIDs.contains(biome.getID())) {
return;
}
immutableIDs.add(biome.getID());
biomes.add(biome);
biomeCount++;
biomes.add(create(biome));
}
public void addBiomeMutable(BCLBiome biome) {
if (immutableIDs.contains(biome.getID())) {
return;
}
biomes.add(biome);
}
public void clearMutables() {
for (int i = biomes.size() - 1; i >= biomeCount; i--) {
biomes.remove(i);
}
}
public BCLBiome getBiome(WorldgenRandom random) {
public Entry getBiome(WorldgenRandom random) {
return biomes.isEmpty() ? null : tree.get(random);
}
public List<BCLBiome> getBiomes() {
return biomes;
}
public boolean containsImmutable(ResourceLocation id) {
return immutableIDs.contains(id);
}
public void removeMutableBiome(ResourceLocation id) {
for (int i = biomeCount; i < biomes.size(); i++) {
BCLBiome biome = biomes.get(i);
if (biome.getID().equals(id)) {
biomes.remove(i);
break;
}
}
}
public void rebuild() {
if (biomes.isEmpty()) {
return;
}
WeightedList<BCLBiome> list = new WeightedList<>();
WeightedList<Entry> list = new WeightedList<>();
biomes.forEach(biome -> {
list.add(biome, biome.getGenChance());
list.add(biome, biome.bclBiome.getGenChance());
});
tree = new WeighTree<>(list);
}

View file

@ -14,7 +14,6 @@ public class GeneratorOptions {
private static Function<Point, Boolean> endLandFunction;
private static boolean customNetherBiomeSource = true;
private static boolean customEndBiomeSource = true;
private static boolean addNetherBiomesByTag = true;
private static boolean addEndBiomesByTag = true;
private static boolean useOldBiomeGenerator = false;
private static boolean verticalBiomes = true;
@ -29,7 +28,6 @@ public class GeneratorOptions {
biomeSizeEndVoid = Configs.GENERATOR_CONFIG.getInt("end.biomeMap", "biomeSizeVoid", 256);
customNetherBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options", "customNetherBiomeSource", true);
customEndBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options", "customEndBiomeSource", true);
addNetherBiomesByTag = Configs.GENERATOR_CONFIG.getBoolean("options", "addNetherBiomesByTag", true);
addEndBiomesByTag = Configs.GENERATOR_CONFIG.getBoolean("options", "addEndBiomesByTag", true);
useOldBiomeGenerator = Configs.GENERATOR_CONFIG.useOldGenerator();
verticalBiomes = Configs.GENERATOR_CONFIG.getBoolean("options", "verticalBiomesInTallNether", true);
@ -89,10 +87,6 @@ public class GeneratorOptions {
return customEndBiomeSource;
}
public static boolean addNetherBiomesByTag() {
return addNetherBiomesByTag;
}
public static boolean addEndBiomesByTag() {
return addEndBiomesByTag;
}

View file

@ -52,7 +52,7 @@ public class MapStack implements BiomeMap {
}
@Override
public BCLBiome getBiome(double x, double y, double z) {
public BiomePicker.Entry getBiome(double x, double y, double z) {
int mapIndex;
if (y < minValue) {
@ -70,7 +70,7 @@ public class MapStack implements BiomeMap {
}
private void onChunkCreation(int cx, int cz, int side) {
BCLBiome[][] biomeMap = new BCLBiome[side][side];
BiomePicker.Entry[][] biomeMap = new BiomePicker.Entry[side][side];
BiomeChunk[] chunks = new BiomeChunk[maps.length];
boolean isNoEmpty = false;
@ -79,8 +79,8 @@ public class MapStack implements BiomeMap {
for (int x = 0; x < side; x++) {
for (int z = 0; z < side; z++) {
if (biomeMap[x][z] == null) {
BCLBiome biome = chunks[i].getBiome(x, z);
if (biome.isVertical()) {
BiomePicker.Entry biome = chunks[i].getBiome(x, z);
if (biome.bclBiome.isVertical()) {
biomeMap[x][z] = biome;
isNoEmpty = true;
}

View file

@ -21,12 +21,12 @@ public class HexBiomeChunk implements BiomeChunk {
private static final byte SIDE_PRE_OFFSET = (byte) Math.round(Math.log(SIDE_PRE) / Math.log(2));
private static final short[][] NEIGHBOURS;
private final BCLBiome[] biomes = new BCLBiome[SIZE];
private final BiomePicker.Entry[] biomes = new BiomePicker.Entry[SIZE];
public HexBiomeChunk(WorldgenRandom random, BiomePicker picker) {
BCLBiome[][] buffers = new BCLBiome[2][SIZE];
BiomePicker.Entry[][] buffers = new BiomePicker.Entry[2][SIZE];
for (BCLBiome[] buffer: buffers) {
for (BiomePicker.Entry[] buffer: buffers) {
Arrays.fill(buffer, null);
}
@ -41,9 +41,9 @@ public class HexBiomeChunk implements BiomeChunk {
boolean hasEmptyCells = true;
byte bufferIndex = 0;
while (hasEmptyCells) {
BCLBiome[] inBuffer = buffers[bufferIndex];
BiomePicker.Entry[] inBuffer = buffers[bufferIndex];
bufferIndex = (byte) ((bufferIndex + 1) & 1);
BCLBiome[] outBuffer = buffers[bufferIndex];
BiomePicker.Entry[] outBuffer = buffers[bufferIndex];
hasEmptyCells = false;
for (short index = SIDE; index < MAX_SIDE; index++) {
@ -65,7 +65,7 @@ public class HexBiomeChunk implements BiomeChunk {
}
}
BCLBiome[] outBuffer = buffers[bufferIndex];
BiomePicker.Entry[] outBuffer = buffers[bufferIndex];
byte preN = (byte) (SIDE_MASK - 2);
for (byte index = 0; index < SIDE; index++) {
outBuffer[getIndex(index, (byte) 0)] = outBuffer[getIndex(index, (byte) 2)];
@ -86,7 +86,7 @@ public class HexBiomeChunk implements BiomeChunk {
System.arraycopy(outBuffer, 0, this.biomes, 0, SIZE);
}
private void circle(BCLBiome[] buffer, short center, BCLBiome biome, BCLBiome mask) {
private void circle(BiomePicker.Entry[] buffer, short center, BiomePicker.Entry biome, BiomePicker.Entry mask) {
if (buffer[center] == mask) {
buffer[center] = biome;
}
@ -108,12 +108,12 @@ public class HexBiomeChunk implements BiomeChunk {
}
@Override
public BCLBiome getBiome(int x, int z) {
public BiomePicker.Entry getBiome(int x, int z) {
return biomes[getIndex(wrap(x), wrap(z))];
}
@Override
public void setBiome(int x, int z, BCLBiome biome) {
public void setBiome(int x, int z, BiomePicker.Entry biome) {
biomes[getIndex(wrap(x), wrap(z))] = biome;
}

View file

@ -50,14 +50,14 @@ public class HexBiomeMap implements BiomeMap {
}
@Override
public BCLBiome getBiome(double x, double y, double z) {
BCLBiome biome = getRawBiome(x, z);
BCLBiome edge = biome.getEdge();
int size = biome.getEdgeSize();
public BiomePicker.Entry getBiome(double x, double y, double z) {
BiomePicker.Entry biome = getRawBiome(x, z);
BiomePicker.Entry edge = biome.getEdge();
int size = biome.bclBiome.getEdgeSize();
if (edge == null && biome.getParentBiome() != null) {
edge = biome.getParentBiome().getEdge();
size = biome.getParentBiome().getEdgeSize();
size = biome.getParentBiome().bclBiome.getEdgeSize();
}
if (edge == null) {
@ -93,7 +93,7 @@ public class HexBiomeMap implements BiomeMap {
this.processor = processor;
}
private BCLBiome getRawBiome(double x, double z) {
private BiomePicker.Entry getRawBiome(double x, double z) {
double px = x / scale * RAD_INNER;
double pz = z / scale;
double dx = rotateX(px, pz);
@ -132,7 +132,7 @@ public class HexBiomeMap implements BiomeMap {
return getChunkBiome(cellX, cellZ);
}
private BCLBiome getChunkBiome(int x, int z) {
private BiomePicker.Entry getChunkBiome(int x, int z) {
int cx = HexBiomeChunk.scaleCoordinate(x);
int cz = HexBiomeChunk.scaleCoordinate(z);

View file

@ -18,11 +18,11 @@ public class SquareBiomeChunk implements BiomeChunk {
private static final int SM_CAPACITY = SM_WIDTH * SM_WIDTH;
private static final int CAPACITY = WIDTH * WIDTH;
private final BCLBiome[] biomes;
private final BiomePicker.Entry[] biomes;
public SquareBiomeChunk(WorldgenRandom random, BiomePicker picker) {
BCLBiome[] PreBio = new BCLBiome[SM_CAPACITY];
biomes = new BCLBiome[CAPACITY];
BiomePicker.Entry[] PreBio = new BiomePicker.Entry[SM_CAPACITY];
biomes = new BiomePicker.Entry[CAPACITY];
for (int x = 0; x < SM_WIDTH; x++) {
int offset = x << SM_BIT_OFFSET;
@ -40,12 +40,12 @@ public class SquareBiomeChunk implements BiomeChunk {
}
@Override
public BCLBiome getBiome(int x, int z) {
public BiomePicker.Entry getBiome(int x, int z) {
return biomes[getIndex(x & MASK_WIDTH, z & MASK_WIDTH)];
}
@Override
public void setBiome(int x, int z, BCLBiome biome) {
public void setBiome(int x, int z, BiomePicker.Entry biome) {
biomes[getIndex(x & MASK_WIDTH, z & MASK_WIDTH)] = biome;
}

View file

@ -45,16 +45,16 @@ public class SquareBiomeMap implements BiomeMap {
}
@Override
public BCLBiome getBiome(double x, double y, double z) {
BCLBiome biome = getRawBiome(x, z);
public BiomePicker.Entry getBiome(double x, double y, double z) {
BiomePicker.Entry biome = getRawBiome(x, z);
if (biome.getEdge() != null || (biome.getParentBiome() != null && biome.getParentBiome().getEdge() != null)) {
BCLBiome search = biome;
BiomePicker.Entry search = biome;
if (biome.getParentBiome() != null) {
search = biome.getParentBiome();
}
int size = search.getEdgeSize();
int size = search.bclBiome.getEdgeSize();
boolean edge = !search.isSame(getRawBiome(x + size, z));
edge = edge || !search.isSame(getRawBiome(x - size, z));
edge = edge || !search.isSame(getRawBiome(x, z + size));
@ -96,7 +96,7 @@ public class SquareBiomeMap implements BiomeMap {
return chunk;
}
private BCLBiome getRawBiome(double bx, double bz) {
private BiomePicker.Entry getRawBiome(double bx, double bz) {
double x = bx * size / sizeXZ;
double z = bz * size / sizeXZ;

View file

@ -4,6 +4,7 @@
"package": "ru.bclib.mixin.common",
"compatibilityLevel": "JAVA_17",
"mixins": [
"BiomeMixin",
"BiomeGenerationSettingsAccessor",
"shears.DiggingEnchantmentMixin",
"shears.ItemPredicateBuilderMixin",