Backportat latest changes from master
This commit is contained in:
parent
9183293329
commit
53911dfe91
63 changed files with 1002 additions and 351 deletions
|
@ -7,8 +7,8 @@ buildscript {
|
|||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
sourceCompatibility = JavaVersion.VERSION_16
|
||||
targetCompatibility = JavaVersion.VERSION_16
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
|
||||
archivesBaseName = project.archives_base_name
|
||||
version = project.mod_version
|
||||
|
|
|
@ -6,12 +6,12 @@ loom_version=0.10-SNAPSHOT
|
|||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/versions.html
|
||||
minecraft_version= 1.18-pre1
|
||||
loader_version= 0.12.5
|
||||
fabric_version = 0.42.2+1.18
|
||||
minecraft_version= 1.18
|
||||
loader_version= 0.12.6
|
||||
fabric_version = 0.43.1+1.18
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 0.5.1
|
||||
mod_version = 0.5.5
|
||||
maven_group = ru.bclib
|
||||
archives_base_name = bclib
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ package ru.bclib;
|
|||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import ru.bclib.api.TagAPI;
|
||||
import ru.bclib.api.WorldDataAPI;
|
||||
|
@ -23,8 +22,6 @@ import ru.bclib.world.generator.BCLibNetherBiomeSource;
|
|||
import ru.bclib.world.generator.GeneratorOptions;
|
||||
import ru.bclib.world.surface.BCLSurfaceBuilders;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
public class BCLib implements ModInitializer {
|
||||
|
|
|
@ -3,7 +3,7 @@ package ru.bclib;
|
|||
import net.minecraft.nbt.CompoundTag;
|
||||
import ru.bclib.api.datafixer.DataFixerAPI;
|
||||
import ru.bclib.api.datafixer.Patch;
|
||||
import ru.bclib.api.datafixer.PatchFunction;
|
||||
import ru.bclib.interfaces.PatchFunction;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
package ru.bclib.api;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.impl.biome.InternalBiomeData;
|
||||
import net.fabricmc.fabric.impl.biome.NetherBiomeData;
|
||||
import net.fabricmc.fabric.impl.biome.TheEndBiomeData;
|
||||
import net.fabricmc.fabric.mixin.biome.modification.GenerationSettingsAccessor;
|
||||
import net.fabricmc.fabric.mixin.biome.modification.SpawnSettingsAccessor;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
|
@ -15,11 +19,16 @@ import net.minecraft.resources.ResourceKey;
|
|||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.random.WeightedRandomList;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Biome.ClimateParameters;
|
||||
import net.minecraft.world.biome.Biome.ClimateParameters;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||
|
@ -31,6 +40,8 @@ import ru.bclib.world.features.BCLFeature;
|
|||
import ru.bclib.world.generator.BiomePicker;
|
||||
import ru.bclib.world.structures.BCLStructureFeature;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
@ -114,8 +125,8 @@ public class BiomeAPI {
|
|||
registerBiome(biome);
|
||||
NETHER_BIOME_PICKER.addBiome(biome);
|
||||
Random random = new Random(biome.getID().hashCode());
|
||||
//TODO: (1.18) did they add depth and scale as two new params here???
|
||||
Climate.ParameterPoint parameters = Climate.parameters(
|
||||
//TODO: (1.18) did they add depth and scale as two new params here???
|
||||
ClimateParameters parameters = new ClimateParameters(
|
||||
MHelper.randRange(-1.5F, 1.5F, random),
|
||||
MHelper.randRange(-1.5F, 1.5F, random),
|
||||
MHelper.randRange(-1.5F, 1.5F, random),
|
||||
|
@ -396,7 +407,10 @@ public class BiomeAPI {
|
|||
biomes.forEach(biome -> {
|
||||
ResourceLocation biomeID = getBiomeID(biome);
|
||||
boolean modify = isDatapackBiome(biomeID);
|
||||
if (!modify && !MODIFIED_BIOMES.contains(biomeID)) {
|
||||
if (biome != BuiltinRegistries.BIOME.get(biomeID)) {
|
||||
modify = true;
|
||||
}
|
||||
else if (!modify && !MODIFIED_BIOMES.contains(biomeID)) {
|
||||
MODIFIED_BIOMES.add(biomeID);
|
||||
modify = true;
|
||||
}
|
||||
|
@ -417,13 +431,7 @@ public class BiomeAPI {
|
|||
public static void addBiomeFeature(Biome biome, ConfiguredFeature feature, Decoration step) {
|
||||
GenerationSettingsAccessor accessor = (GenerationSettingsAccessor) biome.getGenerationSettings();
|
||||
List<List<Supplier<ConfiguredFeature<?, ?>>>> biomeFeatures = getMutableList(accessor.fabric_getFeatures());
|
||||
int index = step.ordinal();
|
||||
if (biomeFeatures.size() < index) {
|
||||
for (int i = biomeFeatures.size(); i <= index; i++) {
|
||||
biomeFeatures.add(Lists.newArrayList());
|
||||
}
|
||||
}
|
||||
List<Supplier<ConfiguredFeature<?, ?>>> list = getMutableList(biomeFeatures.get(index));
|
||||
List<Supplier<ConfiguredFeature<?, ?>>> list = getList(step, biomeFeatures);
|
||||
list.add(() -> feature);
|
||||
accessor.fabric_setFeatures(biomeFeatures);
|
||||
}
|
||||
|
@ -437,18 +445,30 @@ public class BiomeAPI {
|
|||
GenerationSettingsAccessor accessor = (GenerationSettingsAccessor) biome.getGenerationSettings();
|
||||
List<List<Supplier<ConfiguredFeature<?, ?>>>> biomeFeatures = getMutableList(accessor.fabric_getFeatures());
|
||||
for (BCLFeature feature: features) {
|
||||
int index = feature.getFeatureStep().ordinal();
|
||||
if (biomeFeatures.size() < index) {
|
||||
for (int i = biomeFeatures.size(); i <= index; i++) {
|
||||
biomeFeatures.add(Lists.newArrayList());
|
||||
}
|
||||
}
|
||||
List<Supplier<ConfiguredFeature<?, ?>>> list = getMutableList(biomeFeatures.get(index));
|
||||
List<Supplier<ConfiguredFeature<?, ?>>> list = getList(feature.getFeatureStep(), biomeFeatures);
|
||||
list.add(feature::getFeatureConfigured);
|
||||
}
|
||||
accessor.fabric_setFeatures(biomeFeatures);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for correct feature list from all biome feature list of lists.
|
||||
* @param step feature {@link Decoration} step.
|
||||
* @param lists biome accessor lists.
|
||||
* @return mutable {@link ConfiguredFeature} list.
|
||||
*/
|
||||
private static List<Supplier<ConfiguredFeature<?, ?>>> getList(Decoration step, List<List<Supplier<ConfiguredFeature<?, ?>>>> lists) {
|
||||
int index = step.ordinal();
|
||||
if (lists.size() <= index) {
|
||||
for (int i = lists.size(); i <= index; i++) {
|
||||
lists.add(Lists.newArrayList());
|
||||
}
|
||||
}
|
||||
List<Supplier<ConfiguredFeature<?, ?>>> list = getMutableList(lists.get(index));
|
||||
lists.set(index, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds new structure feature to existing biome.
|
||||
* @param biome {@link Biome} to add structure feature in.
|
||||
|
@ -475,10 +495,41 @@ public class BiomeAPI {
|
|||
accessor.fabric_setStructureFeatures(biomeStructures);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds mob spawning to specified biome.
|
||||
* @param biome {@link Biome} to add mob spawning.
|
||||
* @param entityType {@link EntityType} mob type.
|
||||
* @param weight spawn weight.
|
||||
* @param minGroupCount minimum mobs in group.
|
||||
* @param maxGroupCount maximum mobs in group.
|
||||
*/
|
||||
public static <M extends Mob> void addBiomeMobSpawn(Biome biome, EntityType<M> entityType, int weight, int minGroupCount, int maxGroupCount) {
|
||||
MobCategory category = entityType.getCategory();
|
||||
SpawnSettingsAccessor accessor = (SpawnSettingsAccessor) biome.getMobSettings();
|
||||
Map<MobCategory, WeightedRandomList<SpawnerData>> spawners = getMutableMap(accessor.fabric_getSpawners());
|
||||
List<SpawnerData> mobs = spawners.containsKey(category) ? getMutableList(spawners.get(category).unwrap()) : Lists.newArrayList();
|
||||
mobs.add(new SpawnerData(entityType, weight, minGroupCount, maxGroupCount));
|
||||
spawners.put(category, WeightedRandomList.create(mobs));
|
||||
accessor.fabric_setSpawners(spawners);
|
||||
}
|
||||
|
||||
private static <T extends Object> List<T> getMutableList(List<T> input) {
|
||||
if (input instanceof ImmutableList) {
|
||||
if (input!=null) {
|
||||
System.out.println("getMutableList: " + input.getClass().getName());
|
||||
for (Class cl : input.getClass().getInterfaces()){
|
||||
System.out.println(" - " + cl.getName());
|
||||
}
|
||||
}
|
||||
if (/*input instanceof ImmutableList ||*/ !(input instanceof ArrayList || input instanceof LinkedList)) {
|
||||
return Lists.newArrayList(input);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
private static <K extends Object, V extends Object> Map<K, V> getMutableMap(Map<K, V> input) {
|
||||
if (input instanceof ImmutableMap) {
|
||||
return Maps.newHashMap(input);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
|
22
src/main/java/ru/bclib/api/ComposterAPI.java
Normal file
22
src/main/java/ru/bclib/api/ComposterAPI.java
Normal file
|
@ -0,0 +1,22 @@
|
|||
package ru.bclib.api;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import ru.bclib.mixin.common.ComposterBlockAccessor;
|
||||
|
||||
public class ComposterAPI {
|
||||
public static Block allowCompost(float chance, Block block){
|
||||
if (block != null) {
|
||||
allowCompost(chance, block.asItem());
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
public static Item allowCompost(float chance, Item item){
|
||||
if (item != null && item != Items.AIR) {
|
||||
ComposterBlockAccessor.callAdd(chance, item);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
120
src/main/java/ru/bclib/api/LifeCycleAPI.java
Normal file
120
src/main/java/ru/bclib/api/LifeCycleAPI.java
Normal file
|
@ -0,0 +1,120 @@
|
|||
package ru.bclib.api;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
import net.minecraft.world.level.CustomSpawner;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* provides some lifetime hooks for a Minecraft instance
|
||||
*/
|
||||
public class LifeCycleAPI {
|
||||
private final static List<LevelLoadBiomesCall> onLoadLevelBiomes = new ArrayList<>(2);
|
||||
private final static List<LevelLoadCall> onLoadLevel = new ArrayList<>(2);
|
||||
|
||||
/**
|
||||
* A callback function that is used for each new ServerLevel instance
|
||||
*/
|
||||
public interface LevelLoadBiomesCall {
|
||||
void onLoad(ServerLevel world, long seed, Registry<Biome> registry);
|
||||
}
|
||||
|
||||
/**
|
||||
* A callback function that is used for each new ServerLevel instance
|
||||
*/
|
||||
public interface LevelLoadCall {
|
||||
void onLoad(
|
||||
ServerLevel world,
|
||||
MinecraftServer minecraftServer,
|
||||
Executor executor,
|
||||
LevelStorageSource.LevelStorageAccess levelStorageAccess,
|
||||
ServerLevelData serverLevelData,
|
||||
ResourceKey<Level> resourceKey,
|
||||
DimensionType dimensionType,
|
||||
ChunkProgressListener chunkProgressListener,
|
||||
ChunkGenerator chunkGenerator,
|
||||
boolean bl,
|
||||
long l,
|
||||
List<CustomSpawner> list,
|
||||
boolean bl2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback that is called when a new {@code ServerLevel is instantiated}.
|
||||
* This callback will receive the world seed as well as it's biome registry.
|
||||
* @param call The calbback Method
|
||||
*/
|
||||
public static void onLevelLoad(LevelLoadBiomesCall call){
|
||||
onLoadLevelBiomes.add(call);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback that is called when a new {@code ServerLevel is instantiated}.
|
||||
* This callbacl will receiv all parameters that were passed to the ServerLevel's constructor
|
||||
* @param call The calbback Method
|
||||
*/
|
||||
public static void onLevelLoad(LevelLoadCall call){
|
||||
onLoadLevel.add(call);
|
||||
}
|
||||
|
||||
/**
|
||||
* For internal use, You should not call this method!
|
||||
* @param minecraftServer
|
||||
* @param executor
|
||||
* @param levelStorageAccess
|
||||
* @param serverLevelData
|
||||
* @param resourceKey
|
||||
* @param dimensionType
|
||||
* @param chunkProgressListener
|
||||
* @param chunkGenerator
|
||||
* @param bl
|
||||
* @param l
|
||||
* @param list
|
||||
* @param bl2
|
||||
*/
|
||||
public static void _runLevelLoad(ServerLevel world,
|
||||
MinecraftServer minecraftServer,
|
||||
Executor executor,
|
||||
LevelStorageSource.LevelStorageAccess levelStorageAccess,
|
||||
ServerLevelData serverLevelData,
|
||||
ResourceKey<Level> resourceKey,
|
||||
DimensionType dimensionType,
|
||||
ChunkProgressListener chunkProgressListener,
|
||||
ChunkGenerator chunkGenerator,
|
||||
boolean bl,
|
||||
long l,
|
||||
List<CustomSpawner> list,
|
||||
boolean bl2){
|
||||
onLoadLevel.forEach(c -> c.onLoad(
|
||||
world,
|
||||
minecraftServer,
|
||||
executor,
|
||||
levelStorageAccess,
|
||||
serverLevelData,
|
||||
resourceKey,
|
||||
dimensionType,
|
||||
chunkProgressListener,
|
||||
chunkGenerator,
|
||||
bl,
|
||||
l,
|
||||
list,
|
||||
bl2)
|
||||
);
|
||||
|
||||
final long seed = world.getSeed();
|
||||
final Registry<Biome> biomeRegistry = world.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
||||
onLoadLevelBiomes.forEach(c -> c.onLoad(world, seed, biomeRegistry));
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ import ru.bclib.util.Logger;
|
|||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -570,6 +571,9 @@ public class DataFixerAPI {
|
|||
private static List<File> getAllPlayers(File dir) {
|
||||
List<File> list = new ArrayList<>();
|
||||
dir = new File(dir, "playerdata");
|
||||
if (!dir.exists() || !dir.isDirectory()) {
|
||||
return list;
|
||||
}
|
||||
for (File file : dir.listFiles()) {
|
||||
if (file.isFile() && file.getName().endsWith(".dat")) {
|
||||
list.add(file);
|
||||
|
@ -604,7 +608,7 @@ public class DataFixerAPI {
|
|||
private static CompoundTag readNbt(File file) throws IOException {
|
||||
try {
|
||||
return NbtIo.readCompressed(file);
|
||||
} catch (ZipException e){
|
||||
} catch (ZipException | EOFException e){
|
||||
return NbtIo.read(file);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package ru.bclib.api.datafixer;
|
|||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.bclib.interfaces.PatchBiFunction;
|
||||
import ru.bclib.interfaces.PatchFunction;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
|
|
@ -7,6 +7,8 @@ import net.minecraft.nbt.Tag;
|
|||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.bclib.BCLib;
|
||||
import ru.bclib.api.WorldDataAPI;
|
||||
import ru.bclib.interfaces.PatchBiFunction;
|
||||
import ru.bclib.interfaces.PatchFunction;
|
||||
import ru.bclib.util.ModUtil;
|
||||
|
||||
import java.io.File;
|
||||
|
|
|
@ -3,6 +3,8 @@ package ru.bclib.api.datafixer;
|
|||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.bclib.interfaces.PatchBiFunction;
|
||||
import ru.bclib.interfaces.PatchFunction;
|
||||
import ru.bclib.util.ModUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
308
src/main/java/ru/bclib/api/spawning/SpawnRuleBuilder.java
Normal file
308
src/main/java/ru/bclib/api/spawning/SpawnRuleBuilder.java
Normal file
|
@ -0,0 +1,308 @@
|
|||
package ru.bclib.api.spawning;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import net.fabricmc.fabric.mixin.object.builder.SpawnRestrictionAccessor;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.Difficulty;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.SpawnPlacements.SpawnPredicate;
|
||||
import net.minecraft.world.entity.SpawnPlacements.Type;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.levelgen.Heightmap.Types;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import ru.bclib.interfaces.SpawnRule;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class SpawnRuleBuilder<M extends Mob> {
|
||||
private static final Map<String, SpawnRuleEntry> RULES_CACHE = Maps.newHashMap();
|
||||
private static final SpawnRuleBuilder INSTANCE = new SpawnRuleBuilder();
|
||||
private List<SpawnRuleEntry> rules = Lists.newArrayList();
|
||||
private SpawnRuleEntry entryInstance;
|
||||
private EntityType<M> entityType;
|
||||
|
||||
private SpawnRuleBuilder() {}
|
||||
|
||||
/**
|
||||
* Starts new rule building process.
|
||||
* @return prepared {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public static SpawnRuleBuilder start(EntityType<? extends Mob> entityType) {
|
||||
INSTANCE.entityType = entityType;
|
||||
INSTANCE.rules.clear();
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop entity spawn on peaceful {@link Difficulty}
|
||||
* @return same {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public SpawnRuleBuilder notPeaceful() {
|
||||
entryInstance = getFromCache("not_peaceful", () -> {
|
||||
return new SpawnRuleEntry(0, (type, world, spawnReason, pos, random) -> world.getDifficulty() != Difficulty.PEACEFUL);
|
||||
});
|
||||
rules.add(entryInstance);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restricts entity spawn above world surface (flying mobs).
|
||||
* @param minHeight minimal spawn height.
|
||||
* @return same {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public SpawnRuleBuilder aboveGround(int minHeight) {
|
||||
entryInstance = getFromCache("above_ground", () -> {
|
||||
return new SpawnRuleEntry(0, (type, world, spawnReason, pos, random) -> {
|
||||
if (pos.getY() < world.getMinBuildHeight() + 2) {
|
||||
return false;
|
||||
}
|
||||
return pos.getY() > world.getHeight(Types.WORLD_SURFACE, pos.getX(), pos.getZ()) + minHeight;
|
||||
});
|
||||
});
|
||||
rules.add(entryInstance);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restricts entity spawn below world logical height (useful for Nether mobs).
|
||||
* @return same {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public SpawnRuleBuilder belowMaxHeight() {
|
||||
entryInstance = getFromCache("below_max_height", () -> {
|
||||
return new SpawnRuleEntry(0, (type, world, spawnReason, pos, random) -> pos.getY() < world.dimensionType().logicalHeight());
|
||||
});
|
||||
rules.add(entryInstance);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restricts spawning only to vanilla valid blocks.
|
||||
* @return same {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public SpawnRuleBuilder onlyOnValidBlocks() {
|
||||
entryInstance = getFromCache("only_on_valid_blocks", () -> {
|
||||
return new SpawnRuleEntry(0, (type, world, spawnReason, pos, random) -> {
|
||||
BlockPos below = pos.below();
|
||||
return world.getBlockState(below).isValidSpawn(world, below, type);
|
||||
});
|
||||
});
|
||||
rules.add(entryInstance);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restricts spawning only to specified blocks.
|
||||
* @return same {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public SpawnRuleBuilder onlyOnBlocks(Block... blocks) {
|
||||
final Block[] floorBlocks = blocks;
|
||||
Arrays.sort(floorBlocks, Comparator.comparing(Block::getDescriptionId));
|
||||
|
||||
StringBuilder builder = new StringBuilder("only_on_blocks");
|
||||
for (Block block : floorBlocks) {
|
||||
builder.append('_');
|
||||
builder.append(block.getDescriptionId());
|
||||
}
|
||||
|
||||
entryInstance = getFromCache(builder.toString(), () -> {
|
||||
return new SpawnRuleEntry(0, (type, world, spawnReason, pos, random) -> {
|
||||
Block below = world.getBlockState(pos.below()).getBlock();
|
||||
for (Block floor: floorBlocks) {
|
||||
if (floor == below) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
rules.add(entryInstance);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will spawn entity with 1 / chance probability (randomly).
|
||||
* @param chance probability limit.
|
||||
* @return same {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public SpawnRuleBuilder withChance(int chance) {
|
||||
entryInstance = getFromCache("with_chance_" + chance, () -> {
|
||||
return new SpawnRuleEntry(1, (type, world, spawnReason, pos, random) -> random.nextInt(chance) == 0);
|
||||
});
|
||||
rules.add(entryInstance);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will spawn entity only below specified brightness value.
|
||||
* @param lightLevel light level upper limit.
|
||||
* @return same {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public SpawnRuleBuilder belowBrightness(int lightLevel) {
|
||||
entryInstance = getFromCache("below_brightness_" + lightLevel, () -> {
|
||||
return new SpawnRuleEntry(2, (type, world, spawnReason, pos, random) -> world.getMaxLocalRawBrightness(pos) <= lightLevel);
|
||||
});
|
||||
rules.add(entryInstance);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will spawn entity only above specified brightness value.
|
||||
* @param lightLevel light level lower limit.
|
||||
* @return same {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public SpawnRuleBuilder aboveBrightness(int lightLevel) {
|
||||
entryInstance = getFromCache("above_brightness_" + lightLevel, () -> {
|
||||
return new SpawnRuleEntry(2, (type, world, spawnReason, pos, random) -> world.getMaxLocalRawBrightness(pos) >= lightLevel);
|
||||
});
|
||||
rules.add(entryInstance);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entity spawn will follow common vanilla spawn rules - spawn in darkness and not on peaceful level.
|
||||
* @param lightLevel light level upper limit.
|
||||
* @return same {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public SpawnRuleBuilder hostile(int lightLevel) {
|
||||
return notPeaceful().belowBrightness(lightLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Entity spawn will follow common vanilla spawn rules - spawn in darkness (below light level 7) and not on peaceful level.
|
||||
* @return same {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public SpawnRuleBuilder vanillaHostile() {
|
||||
return hostile(7);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will spawn entity only if count of nearby entities will be lower than specified.
|
||||
* @param selectorType selector {@link EntityType} to search.
|
||||
* @param count max entity count.
|
||||
* @param side side of box to search in.
|
||||
* @return same {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public SpawnRuleBuilder maxNearby(EntityType<?> selectorType, int count, int side) {
|
||||
final Class<? extends Entity> baseClass = selectorType.getBaseClass();
|
||||
entryInstance = getFromCache("max_nearby_" + selectorType.getDescriptionId()+"_"+count+"_"+side, () -> {
|
||||
return new SpawnRuleEntry(3, (type, world, spawnReason, pos, random) -> {
|
||||
try {
|
||||
final AABB box = new AABB(pos).inflate(side, world.getHeight(), side);
|
||||
final List<?> list = world.getEntitiesOfClass(baseClass, box, (entity) -> true);
|
||||
return list.size() < count;
|
||||
}
|
||||
catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
rules.add(entryInstance);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will spawn entity only if count of nearby entities with same type will be lower than specified.
|
||||
* @param count max entity count.
|
||||
* @param side side of box to search in.
|
||||
* @return same {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public SpawnRuleBuilder maxNearby(int count, int side) {
|
||||
return maxNearby(entityType, count, side);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will spawn entity only if count of nearby entities with same type will be lower than specified.
|
||||
* @param count max entity count.
|
||||
* @return same {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public SpawnRuleBuilder maxNearby(int count) {
|
||||
return maxNearby(entityType, count, 256);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to add custom spawning rule for specific entities.
|
||||
* @param rule {@link SpawnRule} rule, can be a lambda expression.
|
||||
* @return same {@link SpawnRuleBuilder} instance.
|
||||
*/
|
||||
public SpawnRuleBuilder customRule(SpawnRule rule) {
|
||||
rules.add(new SpawnRuleEntry(7, rule));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize spawning rule creation.
|
||||
* @param spawnType {@link Type} of spawn.
|
||||
* @param heightmapType {@link Types} heightmap type.
|
||||
*/
|
||||
public void build(Type spawnType, Types heightmapType) {
|
||||
final List<SpawnRuleEntry> rulesCopy = Lists.newArrayList(this.rules);
|
||||
Collections.sort(rulesCopy);
|
||||
|
||||
SpawnPredicate<M> predicate = (entityType, serverLevelAccessor, mobSpawnType, blockPos, random) -> {
|
||||
for (SpawnRuleEntry rule: rulesCopy) {
|
||||
if (!rule.canSpawn(entityType, serverLevelAccessor, mobSpawnType, blockPos, random)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
SpawnRestrictionAccessor.callRegister(entityType, spawnType, heightmapType, predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize spawning rule creation with No Restrictions spawn type, useful for flying entities.
|
||||
* @param heightmapType {@link Types} heightmap type.
|
||||
*/
|
||||
public void buildNoRestrictions(Types heightmapType) {
|
||||
build(Type.NO_RESTRICTIONS, heightmapType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize spawning rule creation with On Ground spawn type, useful for common entities.
|
||||
* @param heightmapType {@link Types} heightmap type.
|
||||
*/
|
||||
public void buildOnGround(Types heightmapType) {
|
||||
build(Type.ON_GROUND, heightmapType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize spawning rule creation with In Water spawn type, useful for water entities.
|
||||
* @param heightmapType {@link Types} heightmap type.
|
||||
*/
|
||||
public void buildInWater(Types heightmapType) {
|
||||
build(Type.IN_WATER, heightmapType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize spawning rule creation with In Lava spawn type, useful for lava entities.
|
||||
* @param heightmapType {@link Types} heightmap type.
|
||||
*/
|
||||
public void buildInLava(Types heightmapType) {
|
||||
build(Type.IN_LAVA, heightmapType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function, will take entry from cache or create it if necessary.
|
||||
* @param name {@link String} entry internal name.
|
||||
* @param supplier {@link Supplier} for {@link SpawnRuleEntry}.
|
||||
* @return new or existing {@link SpawnRuleEntry}.
|
||||
*/
|
||||
private static SpawnRuleEntry getFromCache(String name, Supplier<SpawnRuleEntry> supplier) {
|
||||
SpawnRuleEntry entry = RULES_CACHE.get(name);
|
||||
if (entry == null) {
|
||||
entry = supplier.get();
|
||||
RULES_CACHE.put(name, entry);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
}
|
30
src/main/java/ru/bclib/api/spawning/SpawnRuleEntry.java
Normal file
30
src/main/java/ru/bclib/api/spawning/SpawnRuleEntry.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
package ru.bclib.api.spawning;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.bclib.interfaces.SpawnRule;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class SpawnRuleEntry<M extends Mob> implements Comparable<SpawnRuleEntry> {
|
||||
private final SpawnRule rule;
|
||||
private final byte priority;
|
||||
|
||||
public SpawnRuleEntry(int priority, SpawnRule rule) {
|
||||
this.priority = (byte) priority;
|
||||
this.rule = rule;
|
||||
}
|
||||
|
||||
boolean canSpawn(EntityType<M> type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random) {
|
||||
return rule.canSpawn(type, world, spawnReason, pos, random);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull SpawnRuleEntry entry) {
|
||||
return Integer.compare(priority, entry.priority);
|
||||
}
|
||||
}
|
|
@ -94,7 +94,7 @@ public class BaseBarrelBlockEntity extends RandomizableContainerBlockEntity {
|
|||
}
|
||||
|
||||
private void scheduleUpdate() {
|
||||
level.getBlockTicks().scheduleTick(getBlockPos(), getBlockState().getBlock(), 5);
|
||||
level.getBlockTicks().schedule(getBlockPos(), getBlockState().getBlock(), 5);
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
|
|
|
@ -40,7 +40,7 @@ public abstract class BaseAnvilBlock extends AnvilBlock implements BlockModelPro
|
|||
public IntegerProperty durability;
|
||||
|
||||
public BaseAnvilBlock(MaterialColor color) {
|
||||
super(FabricBlockSettings.copyOf(Blocks.ANVIL).mapColor(color));
|
||||
super(FabricBlockSettings.copyOf(Blocks.ANVIL).color(color));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -28,7 +28,7 @@ import java.util.Optional;
|
|||
|
||||
public class BaseChainBlock extends ChainBlock implements BlockModelProvider, RenderLayerProvider {
|
||||
public BaseChainBlock(MaterialColor color) {
|
||||
super(FabricBlockSettings.copyOf(Blocks.CHAIN).mapColor(color));
|
||||
super(FabricBlockSettings.copyOf(Blocks.CHAIN).color(color));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -39,7 +39,7 @@ import java.util.Optional;
|
|||
|
||||
public class BaseFurnaceBlock extends FurnaceBlock implements BlockModelProvider, RenderLayerProvider {
|
||||
public BaseFurnaceBlock(Block source) {
|
||||
super(FabricBlockSettings.copyOf(source).luminance(state -> state.getValue(LIT) ? 13 : 0));
|
||||
super(FabricBlockSettings.copyOf(source).lightLevel(state -> state.getValue(LIT) ? 13 : 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -29,13 +29,13 @@ public class BaseLeavesBlock extends LeavesBlock implements BlockModelProvider,
|
|||
|
||||
private static FabricBlockSettings makeLeaves(MaterialColor color) {
|
||||
return FabricBlockSettings.copyOf(Blocks.OAK_LEAVES)
|
||||
.mapColor(color)
|
||||
.color(color)
|
||||
.breakByTool(FabricToolTags.HOES)
|
||||
.breakByTool(FabricToolTags.SHEARS)
|
||||
.breakByHand(true)
|
||||
.allowsSpawning((state, world, pos, type) -> false)
|
||||
.suffocates((state, world, pos) -> false)
|
||||
.blockVision((state, world, pos) -> false);
|
||||
.isValidSpawn((state, world, pos, type) -> false)
|
||||
.isSuffocating((state, world, pos) -> false)
|
||||
.isViewBlocking((state, world, pos) -> false);
|
||||
}
|
||||
|
||||
public BaseLeavesBlock(Block sapling, MaterialColor color, Consumer<FabricBlockSettings> customizeProperties) {
|
||||
|
@ -54,7 +54,7 @@ public class BaseLeavesBlock extends LeavesBlock implements BlockModelProvider,
|
|||
}
|
||||
|
||||
public BaseLeavesBlock(Block sapling, MaterialColor color, int light) {
|
||||
super(makeLeaves(color).luminance(light));
|
||||
super(makeLeaves(color).lightLevel(light));
|
||||
this.sapling = sapling;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@ public class BaseOreBlock extends OreBlock implements BlockModelProvider {
|
|||
|
||||
public BaseOreBlock(Item drop, int minCount, int maxCount, int experience) {
|
||||
this(drop, minCount, maxCount, experience, FabricBlockSettings.of(Material.STONE, MaterialColor.SAND)
|
||||
.hardness(3F)
|
||||
.resistance(9F)
|
||||
.destroyTime(3F)
|
||||
.explosionResistance(9F)
|
||||
.requiresCorrectToolForDrops()
|
||||
.sound(SoundType.STONE));
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ public class BaseSignBlock extends SignBlock implements BlockModelProvider, Cust
|
|||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||
if (state.getValue(WATERLOGGED)) {
|
||||
world.getLiquidTicks().scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world));
|
||||
world.getFluidTicks().schedule(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world));
|
||||
}
|
||||
if (!canSurvive(state, world, pos)) {
|
||||
return state.getValue(WATERLOGGED) ? state.getFluidState()
|
||||
|
@ -191,6 +191,6 @@ public class BaseSignBlock extends SignBlock implements BlockModelProvider, Cust
|
|||
|
||||
@Override
|
||||
public BlockItem getCustomItem(ResourceLocation blockID, FabricItemSettings settings) {
|
||||
return new BlockItem(this, settings.maxCount(16));
|
||||
return new BlockItem(this, settings.stacksTo(16));
|
||||
}
|
||||
}
|
|
@ -36,7 +36,8 @@ public class BaseSlabBlock extends SlabBlock implements BlockModelProvider {
|
|||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
int count = state.getValue(TYPE) == SlabType.DOUBLE ? 2 : 1;
|
||||
return Collections.singletonList(new ItemStack(this, count));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,7 +20,7 @@ public class BaseStripableLogBlock extends BaseRotatedPillarBlock {
|
|||
private final Block striped;
|
||||
|
||||
public BaseStripableLogBlock(MaterialColor color, Block striped) {
|
||||
super(FabricBlockSettings.copyOf(striped).mapColor(color));
|
||||
super(FabricBlockSettings.copyOf(striped).color(color));
|
||||
this.striped = striped;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ public class SimpleLeavesBlock extends BaseBlockNotFull implements RenderLayerPr
|
|||
public SimpleLeavesBlock(MaterialColor color) {
|
||||
super(FabricBlockSettings.of(Material.LEAVES)
|
||||
.strength(0.2F)
|
||||
.mapColor(color)
|
||||
.color(color)
|
||||
.sound(SoundType.GRASS)
|
||||
.noOcclusion()
|
||||
.isValidSpawn((state, world, pos, type) -> false)
|
||||
|
@ -25,7 +25,7 @@ public class SimpleLeavesBlock extends BaseBlockNotFull implements RenderLayerPr
|
|||
public SimpleLeavesBlock(MaterialColor color, int light) {
|
||||
super(FabricBlockSettings.of(Material.LEAVES)
|
||||
.luminance(light)
|
||||
.mapColor(color)
|
||||
.color(color)
|
||||
.strength(0.2F)
|
||||
.sound(SoundType.GRASS)
|
||||
.noOcclusion()
|
||||
|
|
|
@ -20,7 +20,7 @@ public class StripableBarkBlock extends BaseBarkBlock {
|
|||
private final Block striped;
|
||||
|
||||
public StripableBarkBlock(MaterialColor color, Block striped) {
|
||||
super(FabricBlockSettings.copyOf(striped).mapColor(color));
|
||||
super(FabricBlockSettings.copyOf(striped).color(color));
|
||||
this.striped = striped;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ public abstract class WallMushroomBlock extends BaseWallPlantBlock {
|
|||
.breakByTool(FabricToolTags.AXES)
|
||||
.breakByHand(true)
|
||||
.luminance(light)
|
||||
.hardness(0.2F)
|
||||
.destroyTime(0.2F)
|
||||
.sound(SoundType.GRASS)
|
||||
.sound(SoundType.WOOD)
|
||||
.noCollission());
|
||||
|
|
61
src/main/java/ru/bclib/blocks/properties/StringProperty.java
Normal file
61
src/main/java/ru/bclib/blocks/properties/StringProperty.java
Normal file
|
@ -0,0 +1,61 @@
|
|||
package ru.bclib.blocks.properties;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@Deprecated
|
||||
public class StringProperty extends Property<String> {
|
||||
private final Set<String> values;
|
||||
|
||||
public static StringProperty create(String name, String... values) {
|
||||
return new StringProperty(name, values);
|
||||
}
|
||||
|
||||
protected StringProperty(String string, String... values) {
|
||||
super(string, String.class);
|
||||
this.values = Sets.newHashSet(values);
|
||||
}
|
||||
|
||||
public void addValue(String name) {
|
||||
values.add(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getPossibleValues() {
|
||||
return Collections.unmodifiableSet(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName(String comparable) {
|
||||
return comparable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getValue(String string) {
|
||||
if (values.contains(string)) {
|
||||
return Optional.of(string);
|
||||
}
|
||||
else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int generateHashCode() {
|
||||
return super.generateHashCode() + Objects.hashCode(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof StringProperty that)) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
return values.equals(that.values);
|
||||
}
|
||||
}
|
|
@ -21,8 +21,8 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
public abstract class Config {
|
||||
protected final static Map<AutoSyncID, Config> AUTO_SYNC_CONFIGS = new HashMap<>();
|
||||
public static final String CONFIG_SYNC_PREFIX = "CONFIG_";
|
||||
protected final static Map<AutoSyncID, Config> autoSyncConfigs = new HashMap<>();
|
||||
protected final ConfigKeeper keeper;
|
||||
protected final boolean autoSync;
|
||||
public final String configID;
|
||||
|
@ -51,7 +51,7 @@ public abstract class Config {
|
|||
else
|
||||
DataExchangeAPI.addAutoSyncFile(aid.modID, aid.uniqueID, keeper.getConfigFile());
|
||||
|
||||
autoSyncConfigs.put(aid, this);
|
||||
AUTO_SYNC_CONFIGS.put(aid, this);
|
||||
BCLib.LOGGER.info("Added Config " + configID + " to auto sync (" + (diffContent?"content diff":"file hash") + ")");
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ public abstract class Config {
|
|||
}
|
||||
|
||||
public static void reloadSyncedConfig(AutoSyncID aid, File file) {
|
||||
Config cfg = autoSyncConfigs.get(aid);
|
||||
Config cfg = AUTO_SYNC_CONFIGS.get(aid);
|
||||
if (cfg != null) {
|
||||
cfg.reload();
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ import java.util.function.Supplier;
|
|||
|
||||
public final class ConfigKeeper {
|
||||
private final Map<ConfigKey, Entry<?>> configEntries = Maps.newHashMap();
|
||||
private JsonObject configObject;
|
||||
private final ConfigWriter writer;
|
||||
|
||||
private JsonObject configObject;
|
||||
private boolean changed = false;
|
||||
|
||||
public ConfigKeeper(String modID, String group) {
|
||||
|
@ -33,7 +33,7 @@ public final class ConfigKeeper {
|
|||
this.configObject = writer.load();
|
||||
}
|
||||
|
||||
File getConfigFile() {
|
||||
public File getConfigFile() {
|
||||
return this.writer.getConfigFile();
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,9 @@ public final class ConfigKeeper {
|
|||
}
|
||||
|
||||
String paramKey = key.getEntry();
|
||||
paramKey += " [default: " + entry.getDefault() + "]";
|
||||
if (entry.hasDefaultInName()) {
|
||||
paramKey += " [default: " + entry.getDefault() + "]";
|
||||
}
|
||||
|
||||
this.changed |= entry.setLocation(obj, paramKey);
|
||||
}
|
||||
|
@ -328,7 +330,6 @@ public final class ConfigKeeper {
|
|||
}
|
||||
|
||||
public static class StringArrayEntry extends ArrayEntry<String> {
|
||||
|
||||
public StringArrayEntry(List<String> defaultValue) {
|
||||
super(defaultValue);
|
||||
}
|
||||
|
@ -341,10 +342,14 @@ public final class ConfigKeeper {
|
|||
protected void add(JsonArray array, String el){
|
||||
array.add(el);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasDefaultInName() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static class EnumEntry<T extends Enum<T>> extends Entry<T> {
|
||||
|
||||
private final Type type;
|
||||
|
||||
public EnumEntry(T defaultValue) {
|
||||
|
@ -372,7 +377,6 @@ public final class ConfigKeeper {
|
|||
}
|
||||
|
||||
public static abstract class RangeEntry<T extends Comparable<T>> extends Entry<T> {
|
||||
|
||||
private final T min, max;
|
||||
|
||||
public RangeEntry(T defaultValue, T minVal, T maxVal) {
|
||||
|
@ -396,7 +400,6 @@ public final class ConfigKeeper {
|
|||
}
|
||||
|
||||
public static abstract class Entry<T> {
|
||||
|
||||
protected final T defaultValue;
|
||||
protected Consumer<T> writer;
|
||||
protected Supplier<T> reader;
|
||||
|
@ -448,5 +451,9 @@ public final class ConfigKeeper {
|
|||
public void setDefault() {
|
||||
this.setValue(defaultValue);
|
||||
}
|
||||
|
||||
protected boolean hasDefaultInName() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@ package ru.bclib.config;
|
|||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import ru.bclib.BCLib;
|
||||
import ru.bclib.config.ConfigKeeper.StringArrayEntry;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class Configs {
|
||||
// Client and Server-Config must be the first entries. They are not part of the Auto-Sync process
|
||||
|
@ -11,18 +14,24 @@ public class Configs {
|
|||
public static final ClientConfig CLIENT_CONFIG = new ClientConfig();
|
||||
public static final ServerConfig SERVER_CONFIG = new ServerConfig();
|
||||
|
||||
|
||||
public static final PathConfig GENERATOR_CONFIG = new PathConfig(BCLib.MOD_ID, "generator", false);
|
||||
public static final PathConfig MAIN_CONFIG = new PathConfig(BCLib.MOD_ID, "main", true, true);
|
||||
public static final String MAIN_PATCH_CATEGORY = "patches";
|
||||
|
||||
public static final PathConfig RECIPE_CONFIG = new PathConfig(BCLib.MOD_ID, "recipes");
|
||||
|
||||
public static final PathConfig BIOMES_CONFIG = new PathConfig(BCLib.MOD_ID, "biomes", false);
|
||||
|
||||
public static final String MAIN_PATCH_CATEGORY = "patches";
|
||||
|
||||
public static void save() {
|
||||
MAIN_CONFIG.saveChanges();
|
||||
RECIPE_CONFIG.saveChanges();
|
||||
GENERATOR_CONFIG.saveChanges();
|
||||
initForcedConfig();
|
||||
}
|
||||
|
||||
private static void initForcedConfig() {
|
||||
BIOMES_CONFIG.keeper.registerEntry(new ConfigKey("end_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.saveChanges();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import ru.bclib.config.ConfigKeeper.FloatRange;
|
|||
import ru.bclib.config.ConfigKeeper.IntegerRange;
|
||||
|
||||
public class PathConfig extends Config {
|
||||
|
||||
public PathConfig(String modID, String group, boolean autoSync, boolean diffContent) {
|
||||
super(modID, group, autoSync, diffContent);
|
||||
}
|
||||
|
|
16
src/main/java/ru/bclib/entity/DespawnableAnimal.java
Normal file
16
src/main/java/ru/bclib/entity/DespawnableAnimal.java
Normal file
|
@ -0,0 +1,16 @@
|
|||
package ru.bclib.entity;
|
||||
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.animal.Animal;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
public abstract class DespawnableAnimal extends Animal {
|
||||
protected DespawnableAnimal(EntityType<? extends Animal> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeWhenFarAway(double d) {
|
||||
return !this.hasCustomName();
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ import net.minecraft.network.chat.Component;
|
|||
import net.minecraft.util.Mth;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import ru.bclib.gui.gridlayout.GridLayout.Alignment;
|
||||
import ru.bclib.util.Pair;
|
||||
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package ru.bclib.interfaces;
|
||||
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface IStructureFeatures {
|
||||
public void bclib_registerStructure(Consumer<BiConsumer<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>> callback);
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
package ru.bclib.api.datafixer;
|
||||
package ru.bclib.interfaces;
|
||||
|
||||
import ru.bclib.api.datafixer.MigrationProfile;
|
||||
import ru.bclib.api.datafixer.PatchDidiFailException;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PatchBiFunction<U, V, R> {
|
|
@ -1,4 +1,7 @@
|
|||
package ru.bclib.api.datafixer;
|
||||
package ru.bclib.interfaces;
|
||||
|
||||
import ru.bclib.api.datafixer.MigrationProfile;
|
||||
import ru.bclib.api.datafixer.PatchDidiFailException;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PatchFunction<T, R> {
|
14
src/main/java/ru/bclib/interfaces/SpawnRule.java
Normal file
14
src/main/java/ru/bclib/interfaces/SpawnRule.java
Normal file
|
@ -0,0 +1,14 @@
|
|||
package ru.bclib.interfaces;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SpawnRule<M extends Mob> {
|
||||
boolean canSpawn(EntityType<M> type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random);
|
||||
}
|
|
@ -2,6 +2,7 @@ package ru.bclib.mixin.client;
|
|||
|
||||
import com.mojang.datafixers.util.Function4;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.Minecraft.ExperimentalDialogType;
|
||||
import net.minecraft.client.color.block.BlockColors;
|
||||
import net.minecraft.client.color.item.ItemColors;
|
||||
import net.minecraft.client.main.GameConfig;
|
||||
|
@ -25,11 +26,6 @@ import ru.bclib.api.dataexchange.DataExchangeAPI;
|
|||
import ru.bclib.api.datafixer.DataFixerAPI;
|
||||
import ru.bclib.interfaces.CustomColorProvider;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Mixin(Minecraft.class)
|
||||
|
@ -53,48 +49,13 @@ public abstract class MinecraftMixin {
|
|||
});
|
||||
}
|
||||
|
||||
// @Shadow
|
||||
// protected abstract void doLoadLevel(String string, RegistryHolder registryHolder, Function<LevelStorageAccess, DataPackConfig> function, Function4<LevelStorageAccess, RegistryHolder, ResourceManager, DataPackConfig, WorldData> function4, boolean bl, ExperimentalDialogType experimentalDialogType);
|
||||
//
|
||||
@Shadow
|
||||
protected abstract void doLoadLevel(String string, RegistryHolder registryHolder, Function<LevelStorageAccess, DataPackConfig> function, Function4<LevelStorageAccess, RegistryHolder, ResourceManager, DataPackConfig, WorldData> function4, boolean bl, ExperimentalDialogType experimentalDialogType);
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private LevelStorageSource levelSource;
|
||||
Method doLoadLevel = null;
|
||||
Object experimentalDialogType_BACKUP = null;
|
||||
|
||||
private void bclib_doLoadLevel_BACKUP(String levelID, RegistryHolder registryHolder, Function<LevelStorageAccess, DataPackConfig> function, Function4<LevelStorageAccess, RegistryHolder, ResourceManager, DataPackConfig, WorldData> function4, boolean bl){
|
||||
if (experimentalDialogType_BACKUP==null) {
|
||||
try {
|
||||
Class experimentalDialogType = Class.forName("net.minecraft.client.Minecraft$ExperimentalDialogType");
|
||||
Field f = experimentalDialogType.getDeclaredField("$VALUES");
|
||||
f.setAccessible(true);
|
||||
experimentalDialogType_BACKUP = Array.get(f.get(null), 2);
|
||||
} catch (ClassNotFoundException | IllegalAccessException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (doLoadLevel==null) {
|
||||
for (Method m : Minecraft.class.getDeclaredMethods()) {
|
||||
if (m.getName().equals("doLoadLevel")) {
|
||||
doLoadLevel = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (doLoadLevel!=null && experimentalDialogType_BACKUP!=null){
|
||||
doLoadLevel.setAccessible(true);
|
||||
try {
|
||||
doLoadLevel.invoke(this, new Object[]{levelID, registryHolder, function, function4, bl, experimentalDialogType_BACKUP});
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "loadLevel", cancellable = true, at = @At("HEAD"))
|
||||
private void bclib_callFixerOnLoad(String levelID, CallbackInfo ci) {
|
||||
DataExchangeAPI.prepareServerside();
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package ru.bclib.mixin.client;
|
||||
|
||||
import net.minecraft.data.worldgen.StructureFeatures;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import ru.bclib.interfaces.IStructureFeatures;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Mixin(StructureFeatures.class)
|
||||
public abstract class StructureFeaturesMixin implements IStructureFeatures {
|
||||
@Inject(method="registerStructures", at=@At("TAIL"))
|
||||
private static void bclib_registerStructures(BiConsumer<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>> biConsumer, CallbackInfo ci){
|
||||
bclib_callbacks.forEach(consumer -> consumer.accept(biConsumer));
|
||||
bclib_callbacks.clear();
|
||||
}
|
||||
|
||||
private static List<Consumer<BiConsumer<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>> > bclib_callbacks = new LinkedList<>();
|
||||
public void bclib_registerStructure(Consumer<BiConsumer<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>> callback){
|
||||
bclib_callbacks.add(callback);
|
||||
}
|
||||
}
|
|
@ -2,9 +2,7 @@ package ru.bclib.mixin.common;
|
|||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.WorldGenRegion;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.StructureFeatureManager;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
|
@ -14,17 +12,17 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(ChunkGenerator.class)
|
||||
public class ChunkGeneratorMixin {
|
||||
@Mixin(Biome.class)
|
||||
public class BiomeMixin {
|
||||
private int bclib_featureIteratorSeed;
|
||||
|
||||
@ModifyArg(method = "applyBiomeDecoration", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/WorldgenRandom;setFeatureSeed(JII)V"))
|
||||
@ModifyArg(method = "generate", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/WorldgenRandom;setFeatureSeed(JII)J"))
|
||||
private long bclib_updateFeatureSeed(long seed) {
|
||||
return Long.rotateRight(seed, bclib_featureIteratorSeed++);
|
||||
}
|
||||
|
||||
@Inject(method = "applyBiomeDecoration", at = @At("HEAD"))
|
||||
private void bclib_obBiomeGenerate(WorldGenLevel level, ChunkPos pos, StructureFeatureManager manager, CallbackInfo ci) {
|
||||
@Inject(method = "generate", at = @At("HEAD"))
|
||||
private void bclib_obBiomeGenerate(StructureFeatureManager structureFeatureManager, ChunkGenerator chunkGenerator, WorldGenRegion worldGenRegion, long l, WorldgenRandom worldgenRandom, BlockPos blockPos, CallbackInfo info) {
|
||||
bclib_featureIteratorSeed = 0;
|
||||
}
|
||||
}
|
|
@ -29,7 +29,7 @@ public class BoneMealItemMixin {
|
|||
Level world = context.getLevel();
|
||||
BlockPos blockPos = context.getClickedPos();
|
||||
if (!world.isClientSide) {
|
||||
//BlockPos offset = blockPos.relative(context.getClickedFace());
|
||||
BlockPos offseted = blockPos.relative(context.getClickedFace());
|
||||
if (BonemealAPI.isTerrain(world.getBlockState(blockPos).getBlock())) {
|
||||
boolean consume = false;
|
||||
if (BonemealAPI.isSpreadableTerrain(world.getBlockState(blockPos).getBlock())) {
|
||||
|
|
|
@ -2,8 +2,8 @@ package ru.bclib.mixin.common;
|
|||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.BitStorage;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.SimpleBitStorage;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.chunk.ChunkBiomeContainer;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
|
@ -40,7 +40,7 @@ public class ChunkBiomeContainerMixin implements BiomeSetter {
|
|||
if (bclib_hasHydrogen && be_shouldWriteToHydrogen()) {
|
||||
try {
|
||||
ChunkBiomeContainer self = (ChunkBiomeContainer) (Object) this;
|
||||
BitStorage storage = be_getHydrogenStorage(self);
|
||||
SimpleBitStorage storage = be_getHydrogenStorage(self);
|
||||
Biome[] palette = be_getHydrogenPalette(self);
|
||||
int paletteIndex = be_getHydrogenPaletteIndex(biome, palette);
|
||||
if (paletteIndex == -1) {
|
||||
|
@ -57,7 +57,7 @@ public class ChunkBiomeContainerMixin implements BiomeSetter {
|
|||
catch (Exception e) {
|
||||
int size = storage.getSize();
|
||||
int bits = Mth.ceillog2(palette.length);
|
||||
BitStorage newStorage = new BitStorage(bits, size);
|
||||
SimpleBitStorage newStorage = new SimpleBitStorage(bits, size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
newStorage.set(i, storage.get(i));
|
||||
}
|
||||
|
@ -105,8 +105,8 @@ public class ChunkBiomeContainerMixin implements BiomeSetter {
|
|||
return field;
|
||||
}
|
||||
|
||||
private BitStorage be_getHydrogenStorage(ChunkBiomeContainer container) throws Exception {
|
||||
return (BitStorage) be_getField("intArray").get(container);
|
||||
private SimpleBitStorage be_getHydrogenStorage(ChunkBiomeContainer container) throws Exception {
|
||||
return (SimpleBitStorage) be_getField("intArray").get(container);
|
||||
}
|
||||
|
||||
private Biome[] be_getHydrogenPalette(ChunkBiomeContainer container) throws Exception {
|
||||
|
@ -128,7 +128,7 @@ public class ChunkBiomeContainerMixin implements BiomeSetter {
|
|||
be_getField("palette").set(container, palette);
|
||||
}
|
||||
|
||||
private void be_setHydrogenStorage(ChunkBiomeContainer container, BitStorage storage) throws Exception {
|
||||
private void be_setHydrogenStorage(ChunkBiomeContainer container, SimpleBitStorage storage) throws Exception {
|
||||
be_getField("intArray").set(container, storage);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import net.minecraft.core.MappedRegistry;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.MultiNoiseBiomeSource;
|
||||
import net.minecraft.world.level.biome.TheEndBiomeSource;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
import net.minecraft.world.level.levelgen.synth.NormalNoise;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import ru.bclib.world.generator.BCLibEndBiomeSource;
|
||||
import ru.bclib.world.generator.BCLibNetherBiomeSource;
|
||||
import ru.bclib.world.generator.GeneratorOptions;
|
||||
|
||||
@Mixin(value = DimensionType.class, priority = 100)
|
||||
public class DimensionTypeMixin {
|
||||
@Inject(method="defaultDimensions(Lnet/minecraft/core/RegistryAccess;JZ)Lnet/minecraft/core/MappedRegistry;", at=@At("HEAD"), cancellable = true)
|
||||
static void bclib_defaultDimensions(RegistryAccess registryAccess, long l, boolean bl, CallbackInfoReturnable<MappedRegistry<LevelStem>> cir){
|
||||
MappedRegistry<LevelStem> mappedRegistry = new MappedRegistry<>(Registry.LEVEL_STEM_REGISTRY, Lifecycle.experimental());
|
||||
Registry<DimensionType> registry = registryAccess.registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY);
|
||||
Registry<Biome> registry2 = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY);
|
||||
Registry<NoiseGeneratorSettings> registry3 = registryAccess.registryOrThrow(Registry.NOISE_GENERATOR_SETTINGS_REGISTRY);
|
||||
Registry<NormalNoise.NoiseParameters> registry4 = registryAccess.registryOrThrow(Registry.NOISE_REGISTRY);
|
||||
|
||||
mappedRegistry.register(LevelStem.NETHER, new LevelStem(
|
||||
() -> registry.getOrThrow(DimensionType.NETHER_LOCATION),
|
||||
bclib_replaceNetherBiomeSource(registry2, registry3, registry4, l, bl)
|
||||
), Lifecycle.stable());
|
||||
|
||||
mappedRegistry.register(LevelStem.END, new LevelStem(
|
||||
() -> registry.getOrThrow(DimensionType.END_LOCATION),
|
||||
bclib_replaceEndBiomeSource(registry2, registry3, registry4, l)
|
||||
), Lifecycle.stable());
|
||||
cir.setReturnValue(mappedRegistry);
|
||||
}
|
||||
|
||||
private static ChunkGenerator bclib_replaceNetherBiomeSource(Registry<Biome> biomeRegistry, Registry<NoiseGeneratorSettings> chunkGeneratorSettingsRegistry, Registry<NormalNoise.NoiseParameters> noiseRegistry , long seed, boolean bl) {
|
||||
return new NoiseBasedChunkGenerator(
|
||||
noiseRegistry,
|
||||
GeneratorOptions.customNetherBiomeSource()
|
||||
? new BCLibNetherBiomeSource(biomeRegistry, seed)
|
||||
: MultiNoiseBiomeSource.Preset.NETHER.biomeSource(biomeRegistry, bl),
|
||||
seed,
|
||||
() -> chunkGeneratorSettingsRegistry.getOrThrow(NoiseGeneratorSettings.NETHER)
|
||||
);
|
||||
}
|
||||
|
||||
private static ChunkGenerator bclib_replaceEndBiomeSource(Registry<Biome> biomeRegistry, Registry<NoiseGeneratorSettings> chunkGeneratorSettingsRegistry, Registry<NormalNoise.NoiseParameters> noiseRegistry , long seed) {
|
||||
return new NoiseBasedChunkGenerator(
|
||||
noiseRegistry,
|
||||
GeneratorOptions.customEndBiomeSource()
|
||||
? new BCLibEndBiomeSource(biomeRegistry, seed)
|
||||
: new TheEndBiomeSource(biomeRegistry, seed),
|
||||
seed,
|
||||
() -> chunkGeneratorSettingsRegistry.getOrThrow(NoiseGeneratorSettings.END)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.world.level.chunk.DataLayer;
|
||||
import net.minecraft.world.level.lighting.LayerLightSectionStorage;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(LayerLightSectionStorage.class)
|
||||
public class LayerLightSectionStorageMixin {
|
||||
@Shadow
|
||||
protected DataLayer getDataLayer(long sectionPos, boolean cached) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Inject(method = "getStoredLevel", at = @At(value = "HEAD"), cancellable = true)
|
||||
private void bclib_lightFix(long blockPos, CallbackInfoReturnable<Integer> info) {
|
||||
try {
|
||||
long pos = SectionPos.blockToSection(blockPos);
|
||||
DataLayer dataLayer = this.getDataLayer(pos, true);
|
||||
info.setReturnValue(dataLayer.get(
|
||||
SectionPos.sectionRelative(BlockPos.getX(blockPos)),
|
||||
SectionPos.sectionRelative(BlockPos.getY(blockPos)),
|
||||
SectionPos.sectionRelative(BlockPos.getZ(blockPos))
|
||||
));
|
||||
}
|
||||
catch (Exception e) {
|
||||
info.setReturnValue(0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,7 +12,6 @@ import net.minecraft.server.level.progress.ChunkProgressListenerFactory;
|
|||
import net.minecraft.server.packs.repository.PackRepository;
|
||||
import net.minecraft.server.players.GameProfileCache;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess;
|
||||
import net.minecraft.world.level.storage.WorldData;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
|
@ -17,10 +21,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import ru.bclib.api.BiomeAPI;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Supplier;
|
||||
import ru.bclib.api.LifeCycleAPI;
|
||||
|
||||
@Mixin(ServerLevel.class)
|
||||
public abstract class ServerLevelMixin extends Level {
|
||||
|
@ -32,6 +33,9 @@ public abstract class ServerLevelMixin extends Level {
|
|||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void bclib_onServerWorldInit(MinecraftServer server, Executor workerExecutor, LevelStorageSource.LevelStorageAccess session, ServerLevelData properties, ResourceKey<Level> registryKey, DimensionType dimensionType, ChunkProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long l, List<CustomSpawner> list, boolean bl, CallbackInfo info) {
|
||||
ServerLevel world = ServerLevel.class.cast(this);
|
||||
LifeCycleAPI._runLevelLoad(world, server, workerExecutor, session, properties, registryKey, dimensionType, worldGenerationProgressListener, chunkGenerator, debugWorld, l, list, bl);
|
||||
|
||||
BiomeAPI.initRegistry(server);
|
||||
BiomeAPI.applyModifications(ServerLevel.class.cast(this));
|
||||
|
||||
|
@ -40,5 +44,7 @@ public abstract class ServerLevelMixin extends Level {
|
|||
}
|
||||
|
||||
bclib_lastWorld = session.getLevelId();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ public class SimpleReloadableResourceManagerMixin {
|
|||
};
|
||||
|
||||
@Inject(method = "hasResource", at = @At("HEAD"), cancellable = true)
|
||||
private void hasResource(ResourceLocation resourceLocation, CallbackInfoReturnable<Boolean> info) {
|
||||
private void bclib_hasResource(ResourceLocation resourceLocation, CallbackInfoReturnable<Boolean> info) {
|
||||
if (resourceLocation.getNamespace().equals("minecraft")) {
|
||||
for (String key: BCLIB_MISSING_RESOURCES) {
|
||||
if (resourceLocation.getPath().equals(key)) {
|
||||
|
|
|
@ -3,7 +3,6 @@ package ru.bclib.mixin.common;
|
|||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.WorldGenRegion;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
@ -15,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
public class WorldGenRegionMixin {
|
||||
@Final
|
||||
@Shadow
|
||||
private ChunkAccess center;
|
||||
private ChunkPos center;
|
||||
|
||||
@Inject(method = "ensureCanWrite", at = @At("HEAD"), cancellable = true)
|
||||
private void be_alterBlockCheck(BlockPos blockPos, CallbackInfoReturnable<Boolean> info) {
|
||||
|
|
|
@ -140,13 +140,12 @@ public class AnvilRecipe implements Recipe<Container>, UnknownReceipBookCategory
|
|||
@Override
|
||||
public NonNullList<Ingredient> getIngredients() {
|
||||
NonNullList<Ingredient> defaultedList = NonNullList.create();
|
||||
defaultedList.add(Ingredient.of(TagAPI.ITEM_HAMMERS.getValues()
|
||||
.stream()
|
||||
.filter(hammer -> ((TieredItem) hammer).getTier()
|
||||
.getLevel() >= toolLevel)
|
||||
.map(ItemStack::new)));
|
||||
defaultedList.add(Ingredient.of(TagAPI.ITEM_HAMMERS
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(hammer -> ((TieredItem) hammer).getTier().getLevel() >= toolLevel)
|
||||
.map(ItemStack::new)));
|
||||
defaultedList.add(input);
|
||||
|
||||
return defaultedList;
|
||||
}
|
||||
|
||||
|
@ -252,7 +251,7 @@ public class AnvilRecipe implements Recipe<Container>, UnknownReceipBookCategory
|
|||
}
|
||||
|
||||
public Builder checkConfig(PathConfig config) {
|
||||
exist |= config.getBoolean("anvil", id.getPath(), true);
|
||||
exist &= config.getBoolean("anvil", id.getPath(), true);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ public class FurnaceRecipe {
|
|||
}
|
||||
|
||||
public FurnaceRecipe checkConfig(PathConfig config) {
|
||||
exist |= config.getBoolean("furnace", id.getPath(), true);
|
||||
exist &= config.getBoolean("furnace", id.getPath(), true);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ public class GridRecipe {
|
|||
}
|
||||
|
||||
public GridRecipe checkConfig(PathConfig config) {
|
||||
exist |= config.getBoolean("grid", id.getPath(), true);
|
||||
exist &= config.getBoolean("grid", id.getPath(), true);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ public class SmithingTableRecipe {
|
|||
private SmithingTableRecipe() {}
|
||||
|
||||
public SmithingTableRecipe checkConfig(PathConfig config) {
|
||||
exist |= config.getBoolean("smithing", id.getPath(), true);
|
||||
exist &= config.getBoolean("smithing", id.getPath(), true);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ import java.nio.file.Path;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
|
|
@ -7,6 +7,8 @@ import com.google.gson.JsonObject;
|
|||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
import ru.bclib.config.Configs;
|
||||
import ru.bclib.util.JsonFactory;
|
||||
import ru.bclib.util.StructureHelper;
|
||||
import ru.bclib.util.WeightedList;
|
||||
|
@ -38,6 +40,7 @@ public class BCLBiome {
|
|||
private Biome actualBiome;
|
||||
|
||||
public BCLBiome(BCLBiomeDef definition) {
|
||||
definition.loadConfigValues(Configs.BIOMES_CONFIG);
|
||||
this.mcID = definition.getID();
|
||||
this.readStructureList();
|
||||
if (structuresFeature != null) {
|
||||
|
@ -53,8 +56,15 @@ public class BCLBiome {
|
|||
public BCLBiome(ResourceLocation id, Biome biome, float fogDensity, float genChance) {
|
||||
this.mcID = id;
|
||||
this.biome = biome;
|
||||
this.genChance = genChance;
|
||||
this.fogDensity = fogDensity;
|
||||
if (id.equals(Biomes.THE_VOID.location())) {
|
||||
this.genChance = fogDensity;
|
||||
this.fogDensity = genChance;
|
||||
}
|
||||
else {
|
||||
String biomePath = id.getNamespace() + "." + id.getPath();
|
||||
this.genChance = Configs.BIOMES_CONFIG.getFloat(biomePath, "generation_chance", genChance);
|
||||
this.fogDensity = Configs.BIOMES_CONFIG.getFloat(biomePath, "fog_density", fogDensity);
|
||||
}
|
||||
this.readStructureList();
|
||||
this.customData = Maps.newHashMap();
|
||||
subbiomes.add(this, 1);
|
||||
|
|
|
@ -4,8 +4,6 @@ import com.google.common.collect.Lists;
|
|||
import com.google.common.collect.Maps;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.data.worldgen.StructureFeatures;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.Music;
|
||||
import net.minecraft.sounds.Musics;
|
||||
|
@ -33,9 +31,8 @@ import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
|||
import net.minecraft.world.level.levelgen.surfacebuilders.ConfiguredSurfaceBuilder;
|
||||
import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilder;
|
||||
import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilderBaseConfiguration;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import ru.bclib.config.IdConfig;
|
||||
import ru.bclib.interfaces.IStructureFeatures;
|
||||
import ru.bclib.config.PathConfig;
|
||||
import ru.bclib.util.ColorUtil;
|
||||
import ru.bclib.world.features.BCLFeature;
|
||||
import ru.bclib.world.structures.BCLStructureFeature;
|
||||
|
@ -48,8 +45,7 @@ public class BCLBiomeDef {
|
|||
public static final int DEF_FOLIAGE_OVERWORLD = ColorUtil.color(110, 143, 64);
|
||||
public static final int DEF_FOLIAGE_NETHER = ColorUtil.color(117, 10, 10);
|
||||
public static final int DEF_FOLIAGE_END = ColorUtil.color(197, 210, 112);
|
||||
|
||||
protected final IStructureFeatures structureFeatures = (IStructureFeatures)new StructureFeatures();
|
||||
|
||||
private final List<ConfiguredStructureFeature<?, ?>> structures = Lists.newArrayList();
|
||||
private final List<FeatureInfo> features = Lists.newArrayList();
|
||||
private final List<CarverInfo> carvers = Lists.newArrayList();
|
||||
|
@ -118,7 +114,6 @@ public class BCLBiomeDef {
|
|||
|
||||
/**
|
||||
* Used to load biome settings from config.
|
||||
*
|
||||
* @param config - {@link IdConfig}.
|
||||
* @return this {@link BCLBiomeDef}.
|
||||
*/
|
||||
|
@ -129,9 +124,21 @@ public class BCLBiomeDef {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to load biome settings from config.
|
||||
* @param config - {@link PathConfig}.
|
||||
* @return this {@link BCLBiomeDef}.
|
||||
*/
|
||||
public BCLBiomeDef loadConfigValues(PathConfig config) {
|
||||
String biomePath = id.getNamespace() + "." + id.getPath();
|
||||
this.fogDensity = config.getFloat(biomePath, "fog_density", this.fogDensity);
|
||||
this.genChance = config.getFloat(biomePath, "generation_chance", this.genChance);
|
||||
this.edgeSize = config.getInt(biomePath, "edge_size", this.edgeSize);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set category of the biome.
|
||||
*
|
||||
* @param category - {@link BiomeCategory}.
|
||||
* @return this {@link BCLBiomeDef}.
|
||||
*/
|
||||
|
@ -340,8 +347,7 @@ public class BCLBiomeDef {
|
|||
});
|
||||
|
||||
generationSettings.surfaceBuilder(surface == null ? net.minecraft.data.worldgen.SurfaceBuilders.END : surface);
|
||||
//TODO: (1.18) Removed now. Seems to part of a registry step per biome now
|
||||
//structures.forEach((structure) -> generationSettings.addStructureStart(structure));
|
||||
structures.forEach((structure) -> generationSettings.addStructureStart(structure));
|
||||
features.forEach((info) -> generationSettings.addFeature(info.featureStep, info.feature));
|
||||
carvers.forEach((info) -> generationSettings.addCarver(info.carverStep, info.carver));
|
||||
|
||||
|
@ -359,27 +365,17 @@ public class BCLBiomeDef {
|
|||
if (particleConfig != null) effects.ambientParticle(particleConfig);
|
||||
effects.backgroundMusic(music != null ? new Music(music, 600, 2400, true) : Musics.END);
|
||||
|
||||
Biome biome = new Biome.BiomeBuilder().precipitation(precipitation)
|
||||
.biomeCategory(category)
|
||||
//.depth(depth) //TODO: No longer available in 1.18
|
||||
//.scale(0.2F)
|
||||
.temperature(temperature)
|
||||
.downfall(downfall)
|
||||
.specialEffects(effects.build())
|
||||
.mobSpawnSettings(spawnSettings.build())
|
||||
.generationSettings(generationSettings.build())
|
||||
.build();
|
||||
|
||||
structureFeatures.bclib_registerStructure(biConsumer -> {
|
||||
ResourceKey<Biome> biomeKey = ResourceKey.create(Registry.BIOME_REGISTRY, BuiltinRegistries.BIOME.getKey(biome));
|
||||
System.out.println("Biome:" + biomeKey);
|
||||
structures.forEach((structure) -> {
|
||||
biConsumer.accept(structure, biomeKey);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
return biome;
|
||||
return new Biome.BiomeBuilder()
|
||||
.precipitation(precipitation)
|
||||
.biomeCategory(category)
|
||||
.depth(depth)
|
||||
.scale(0.2F)
|
||||
.temperature(temperature)
|
||||
.downfall(downfall)
|
||||
.effects(effects.build())
|
||||
.spawnSettings(spawnSettings.build())
|
||||
.generationSettings(generationSettings.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
private static final class SpawnInfo {
|
||||
|
|
|
@ -4,11 +4,9 @@ import net.minecraft.core.Registry;
|
|||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
|
||||
import net.minecraft.world.level.levelgen.VerticalAnchor;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||
|
@ -16,59 +14,81 @@ import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguratio
|
|||
import net.minecraft.world.level.levelgen.placement.ChanceDecoratorConfiguration;
|
||||
import net.minecraft.world.level.levelgen.placement.FeatureDecorator;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.BlockMatchTest;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.RuleTest;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.TagMatchTest;
|
||||
import ru.bclib.api.TagAPI;
|
||||
|
||||
public class BCLFeature {
|
||||
private static final RuleTest ANY_TERRAIN = new TagMatchTest(TagAPI.BLOCK_GEN_TERRAIN);
|
||||
private ConfiguredFeature<?, ?> featureConfigured;
|
||||
private GenerationStep.Decoration featureStep;
|
||||
private Feature<?> feature;
|
||||
private Decoration featureStep;
|
||||
private net.minecraft.world.level.levelgen.feature.Feature<?> feature;
|
||||
|
||||
public BCLFeature(Feature<?> feature, ConfiguredFeature<?, ?> configuredFeature, GenerationStep.Decoration featureStep) {
|
||||
public BCLFeature(net.minecraft.world.level.levelgen.feature.Feature<?> feature, ConfiguredFeature<?, ?> configuredFeature, Decoration featureStep) {
|
||||
this.featureConfigured = configuredFeature;
|
||||
this.featureStep = featureStep;
|
||||
this.feature = feature;
|
||||
}
|
||||
|
||||
public BCLFeature(ResourceLocation id, Feature<NoneFeatureConfiguration> feature, GenerationStep.Decoration featureStep, ConfiguredFeature<?, ?> configuredFeature) {
|
||||
public BCLFeature(ResourceLocation id, net.minecraft.world.level.levelgen.feature.Feature<NoneFeatureConfiguration> feature, Decoration featureStep, ConfiguredFeature<?, ?> configuredFeature) {
|
||||
this.featureConfigured = Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, id, configuredFeature);
|
||||
this.feature = Registry.register(Registry.FEATURE, id, feature);
|
||||
this.featureStep = featureStep;
|
||||
}
|
||||
|
||||
public static BCLFeature makeVegetationFeature(ResourceLocation id, Feature<NoneFeatureConfiguration> feature, int density) {
|
||||
/**
|
||||
* Get raw feature.
|
||||
* @return {@link net.minecraft.world.level.levelgen.feature.Feature}.
|
||||
*/
|
||||
public net.minecraft.world.level.levelgen.feature.Feature<?> getFeature() {
|
||||
return feature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get configured feature.
|
||||
* @return {@link ConfiguredFeature}.
|
||||
*/
|
||||
public ConfiguredFeature<?, ?> getFeatureConfigured() {
|
||||
return featureConfigured;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get feature decoration step.
|
||||
* @return {@link Decoration}.
|
||||
*/
|
||||
public Decoration getFeatureStep() {
|
||||
return featureStep;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will create a basic plant feature.
|
||||
* @param id {@link ResourceLocation} feature ID.
|
||||
* @param feature {@link net.minecraft.world.level.levelgen.feature.Feature} with {@link NoneFeatureConfiguration} config.
|
||||
* @param density iterations per chunk.
|
||||
* @return new BCLFeature instance.
|
||||
*/
|
||||
public static BCLFeature makeVegetationFeature(ResourceLocation id, net.minecraft.world.level.levelgen.feature.Feature<NoneFeatureConfiguration> feature, int density) {
|
||||
ConfiguredFeature<?, ?> configured = feature
|
||||
.configured(FeatureConfiguration.NONE)
|
||||
.decorated(BCLDecorators.HEIGHTMAP_SQUARE)
|
||||
.countRandom(density);
|
||||
return new BCLFeature(id, feature, GenerationStep.Decoration.VEGETAL_DECORATION, configured);
|
||||
return new BCLFeature(id, feature, Decoration.VEGETAL_DECORATION, configured);
|
||||
}
|
||||
|
||||
public static BCLFeature makeRawGenFeature(ResourceLocation id, Feature<NoneFeatureConfiguration> feature, int chance) {
|
||||
ConfiguredFeature<?, ?> configured = feature
|
||||
.configured(FeatureConfiguration.NONE)
|
||||
.decorated(FeatureDecorator.CHANCE.configured(new ChanceDecoratorConfiguration(chance)));
|
||||
return new BCLFeature(id, feature, GenerationStep.Decoration.RAW_GENERATION, configured);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static BCLFeature makeLakeFeature(ResourceLocation id, Feature<NoneFeatureConfiguration> feature, int chance) {
|
||||
ConfiguredFeature<?, ?> configured = feature
|
||||
.configured(FeatureConfiguration.NONE)
|
||||
.decorated(FeatureDecorator.LAVA_LAKE.configured(new ChanceDecoratorConfiguration(chance)));
|
||||
return new BCLFeature(id, feature, GenerationStep.Decoration.LAKES, configured);
|
||||
}
|
||||
|
||||
public static BCLFeature makeOreFeature(ResourceLocation id, Block blockOre, int veins, int veinSize, int offset, int minY, int maxY) {
|
||||
/**
|
||||
* Will create a basic ore feature.
|
||||
* @param id {@link ResourceLocation} feature ID.
|
||||
* @param blockOre {@link Decoration} feature step.
|
||||
* @param hostBlock {@link Block} to generate feature in.
|
||||
* @param veins iterations per chunk.
|
||||
* @param veinSize size of ore vein.
|
||||
* @param minY minimum height.
|
||||
* @param maxY maximum height.
|
||||
* @return new BCLFeature instance.
|
||||
*/
|
||||
public static BCLFeature makeOreFeature(ResourceLocation id, Block blockOre, Block hostBlock, int veins, int veinSize, int minY, int maxY) {
|
||||
OreConfiguration featureConfig = new OreConfiguration(
|
||||
new BlockMatchTest(Blocks.END_STONE),
|
||||
new BlockMatchTest(hostBlock),
|
||||
blockOre.defaultBlockState(),
|
||||
veinSize
|
||||
);
|
||||
OreConfiguration config = new OreConfiguration(ANY_TERRAIN, blockOre.defaultBlockState(), 33);
|
||||
ConfiguredFeature<?, ?> oreFeature = Feature.ORE
|
||||
ConfiguredFeature<?, ?> oreFeature = net.minecraft.world.level.levelgen.feature.Feature.ORE
|
||||
.configured(featureConfig)
|
||||
.rangeUniform(
|
||||
VerticalAnchor.absolute(minY),
|
||||
|
@ -77,46 +97,95 @@ public class BCLFeature {
|
|||
.squared()
|
||||
.count(veins);
|
||||
return new BCLFeature(
|
||||
Feature.ORE,
|
||||
net.minecraft.world.level.levelgen.feature.Feature.ORE,
|
||||
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, id, oreFeature),
|
||||
GenerationStep.Decoration.UNDERGROUND_ORES
|
||||
Decoration.UNDERGROUND_ORES
|
||||
);
|
||||
}
|
||||
|
||||
public static BCLFeature makeChunkFeature(ResourceLocation id, Feature<NoneFeatureConfiguration> feature) {
|
||||
/**
|
||||
* Will create feature which will be generated once in each chunk.
|
||||
* @param id {@link ResourceLocation} feature ID.
|
||||
* @param step {@link Decoration} feature step.
|
||||
* @param feature {@link net.minecraft.world.level.levelgen.feature.Feature} with {@link NoneFeatureConfiguration} config.
|
||||
* @return new BCLFeature instance.
|
||||
*/
|
||||
public static BCLFeature makeChunkFeature(ResourceLocation id, Decoration step, net.minecraft.world.level.levelgen.feature.Feature<NoneFeatureConfiguration> feature) {
|
||||
ConfiguredFeature<?, ?> configured = feature
|
||||
.configured(FeatureConfiguration.NONE)
|
||||
.decorated(FeatureDecorator.COUNT.configured(new CountConfiguration(1)));
|
||||
return new BCLFeature(id, feature, GenerationStep.Decoration.LOCAL_MODIFICATIONS, configured);
|
||||
return new BCLFeature(id, feature, step, configured);
|
||||
}
|
||||
|
||||
public static BCLFeature makeChansedFeature(ResourceLocation id, Feature<NoneFeatureConfiguration> feature, int chance) {
|
||||
/**
|
||||
* Will create feature with chanced decoration, chance for feature to generate per chunk is 1 / chance.
|
||||
* @param id {@link ResourceLocation} feature ID.
|
||||
* @param step {@link Decoration} feature step.
|
||||
* @param feature {@link net.minecraft.world.level.levelgen.feature.Feature} with {@link NoneFeatureConfiguration} config.
|
||||
* @param chance chance for feature to be generated in.
|
||||
* @return new BCLFeature instance.
|
||||
*/
|
||||
public static BCLFeature makeChancedFeature(ResourceLocation id, Decoration step, net.minecraft.world.level.levelgen.feature.Feature<NoneFeatureConfiguration> feature, int chance) {
|
||||
ConfiguredFeature<?, ?> configured = feature
|
||||
.configured(FeatureConfiguration.NONE)
|
||||
.decorated(FeatureDecorator.CHANCE.configured(new ChanceDecoratorConfiguration(chance)));
|
||||
return new BCLFeature(id, feature, GenerationStep.Decoration.SURFACE_STRUCTURES, configured);
|
||||
return new BCLFeature(id, feature, step, configured);
|
||||
}
|
||||
|
||||
public static BCLFeature makeCountRawFeature(ResourceLocation id, Feature<NoneFeatureConfiguration> feature, int chance) {
|
||||
ConfiguredFeature<?, ?> configured = feature.configured(FeatureConfiguration.NONE)
|
||||
.decorated(FeatureDecorator.COUNT.configured(new CountConfiguration(chance)));
|
||||
return new BCLFeature(id, feature, GenerationStep.Decoration.RAW_GENERATION, configured);
|
||||
/**
|
||||
* Will create feature with specified generation iterations per chunk.
|
||||
* @param id {@link ResourceLocation} feature ID.
|
||||
* @param step {@link Decoration} feature step.
|
||||
* @param feature {@link net.minecraft.world.level.levelgen.feature.Feature} with {@link NoneFeatureConfiguration} config.
|
||||
* @param count iterations steps.
|
||||
* @return new BCLFeature instance.
|
||||
*/
|
||||
public static BCLFeature makeCountFeature(ResourceLocation id, Decoration step, net.minecraft.world.level.levelgen.feature.Feature<NoneFeatureConfiguration> feature, int count) {
|
||||
ConfiguredFeature<?, ?> configured = feature
|
||||
.configured(FeatureConfiguration.NONE)
|
||||
.decorated(FeatureDecorator.COUNT.configured(new CountConfiguration(count)));
|
||||
return new BCLFeature(id, feature, step, configured);
|
||||
}
|
||||
|
||||
public static BCLFeature makeFeatureConfigured(ResourceLocation id, Feature<NoneFeatureConfiguration> feature) {
|
||||
/**
|
||||
* Makes simple configured feature with {@link NoneFeatureConfiguration} set to NONE.
|
||||
* @param id {@link ResourceLocation} feature ID.
|
||||
* @param step {@link Decoration} feature step.
|
||||
* @param feature {@link net.minecraft.world.level.levelgen.feature.Feature} with {@link NoneFeatureConfiguration} config.
|
||||
* @return new BCLFeature instance.
|
||||
*/
|
||||
public static BCLFeature makeFeatureConfigured(ResourceLocation id, Decoration step, net.minecraft.world.level.levelgen.feature.Feature<NoneFeatureConfiguration> feature) {
|
||||
ConfiguredFeature<?, ?> configured = feature.configured(FeatureConfiguration.NONE);
|
||||
return new BCLFeature(id, feature, GenerationStep.Decoration.RAW_GENERATION, configured);
|
||||
return new BCLFeature(id, feature, step, configured);
|
||||
}
|
||||
|
||||
public Feature<?> getFeature() {
|
||||
return feature;
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeOreFeature(ResourceLocation id, Block blockOre, Block hostBlock, int veins, int veinSize, int offset, int minY, int maxY) {
|
||||
return makeOreFeature(id, blockOre, hostBlock, veins, veinSize, minY, maxY);
|
||||
}
|
||||
|
||||
public ConfiguredFeature<?, ?> getFeatureConfigured() {
|
||||
return featureConfigured;
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeRawGenFeature(ResourceLocation id, net.minecraft.world.level.levelgen.feature.Feature<NoneFeatureConfiguration> feature, int chance) {
|
||||
return makeChancedFeature(id, Decoration.RAW_GENERATION, feature, chance);
|
||||
}
|
||||
|
||||
public GenerationStep.Decoration getFeatureStep() {
|
||||
return featureStep;
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeChunkFeature(ResourceLocation id, net.minecraft.world.level.levelgen.feature.Feature<NoneFeatureConfiguration> feature) {
|
||||
return makeChunkFeature(id, Decoration.LOCAL_MODIFICATIONS, feature);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeChansedFeature(ResourceLocation id, net.minecraft.world.level.levelgen.feature.Feature<NoneFeatureConfiguration> feature, int chance) {
|
||||
return makeChancedFeature(id, Decoration.SURFACE_STRUCTURES, feature, chance);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeCountRawFeature(ResourceLocation id, net.minecraft.world.level.levelgen.feature.Feature<NoneFeatureConfiguration> feature, int chance) {
|
||||
return makeCountFeature(id, Decoration.RAW_GENERATION, feature, chance);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeFeatureConfigured(ResourceLocation id, net.minecraft.world.level.levelgen.feature.Feature<NoneFeatureConfiguration> feature) {
|
||||
return makeFeatureConfigured(id, Decoration.RAW_GENERATION, feature);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConf
|
|||
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
||||
import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilderConfiguration;
|
||||
import ru.bclib.api.BiomeAPI;
|
||||
import ru.bclib.api.TagAPI;
|
||||
import ru.bclib.util.BlocksHelper;
|
||||
|
|
|
@ -9,13 +9,13 @@ import net.minecraft.world.level.biome.Biome;
|
|||
import net.minecraft.world.level.biome.Biome.BiomeCategory;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
import net.minecraft.world.level.biome.Climate;
|
||||
import net.minecraft.world.level.biome.TheEndBiomeSource;
|
||||
import net.minecraft.world.level.levelgen.LegacyRandomSource;
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
import net.minecraft.world.level.levelgen.synth.SimplexNoise;
|
||||
import ru.bclib.BCLib;
|
||||
import ru.bclib.api.BiomeAPI;
|
||||
import ru.bclib.config.ConfigKeeper.StringArrayEntry;
|
||||
import ru.bclib.config.Configs;
|
||||
import ru.bclib.noise.OpenSimplexNoise;
|
||||
import ru.bclib.world.biomes.BCLBiome;
|
||||
|
||||
|
@ -48,7 +48,7 @@ public class BCLibEndBiomeSource extends BiomeSource {
|
|||
BiomeAPI.END_LAND_BIOME_PICKER.clearMutables();
|
||||
BiomeAPI.END_VOID_BIOME_PICKER.clearMutables();
|
||||
|
||||
this.possibleBiomes().forEach(biome -> {
|
||||
this.possibleBiomes.forEach(biome -> {
|
||||
ResourceLocation key = biomeRegistry.getKey(biome);
|
||||
if (!BiomeAPI.hasBiome(key)) {
|
||||
BCLBiome bclBiome = new BCLBiome(key, biome, 1, 1);
|
||||
|
@ -64,6 +64,8 @@ public class BCLibEndBiomeSource extends BiomeSource {
|
|||
}
|
||||
});
|
||||
|
||||
Configs.BIOMES_CONFIG.saveChanges();
|
||||
|
||||
BiomeAPI.END_LAND_BIOME_PICKER.getBiomes().forEach(biome -> biome.updateActualBiomes(biomeRegistry));
|
||||
BiomeAPI.END_VOID_BIOME_PICKER.getBiomes().forEach(biome -> biome.updateActualBiomes(biomeRegistry));
|
||||
|
||||
|
@ -86,8 +88,19 @@ public class BCLibEndBiomeSource extends BiomeSource {
|
|||
}
|
||||
|
||||
private static List<Biome> getBiomes(Registry<Biome> biomeRegistry) {
|
||||
List<String> include = Configs.BIOMES_CONFIG.getEntry("force_include", "end_biomes", StringArrayEntry.class).getValue();
|
||||
|
||||
return biomeRegistry.stream().filter(biome -> {
|
||||
ResourceLocation key = biomeRegistry.getKey(biome);
|
||||
|
||||
if (include.contains(key.toString())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GeneratorOptions.addEndBiomesByCategory() && biome.getBiomeCategory() == BiomeCategory.THEEND) {
|
||||
return true;
|
||||
}
|
||||
|
||||
BCLBiome bclBiome = BiomeAPI.getBiome(key);
|
||||
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
|
||||
if (bclBiome.hasParentBiome()) {
|
||||
|
@ -100,7 +113,7 @@ public class BCLibEndBiomeSource extends BiomeSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Biome getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.Sampler sampler) {
|
||||
public Biome getBiomeForNoiseGen(int biomeX, int biomeY, int biomeZ) {
|
||||
long i = (long) biomeX * (long) biomeX;
|
||||
long j = (long) biomeZ * (long) biomeZ;
|
||||
long check = GeneratorOptions.isFarEndBiomes() ? 65536L : 625L;
|
||||
|
|
|
@ -8,9 +8,10 @@ import net.minecraft.resources.ResourceLocation;
|
|||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Biome.BiomeCategory;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.Climate;
|
||||
import ru.bclib.BCLib;
|
||||
import ru.bclib.api.BiomeAPI;
|
||||
import ru.bclib.config.ConfigKeeper.StringArrayEntry;
|
||||
import ru.bclib.config.Configs;
|
||||
import ru.bclib.world.biomes.BCLBiome;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
@ -37,7 +38,7 @@ public class BCLibNetherBiomeSource extends BiomeSource {
|
|||
|
||||
BiomeAPI.NETHER_BIOME_PICKER.clearMutables();
|
||||
|
||||
this.possibleBiomes().forEach(biome -> {
|
||||
this.possibleBiomes.forEach(biome -> {
|
||||
ResourceLocation key = biomeRegistry.getKey(biome);
|
||||
if (!BiomeAPI.hasBiome(key)) {
|
||||
BCLBiome bclBiome = new BCLBiome(key, biome, 1, 1);
|
||||
|
@ -53,6 +54,7 @@ public class BCLibNetherBiomeSource extends BiomeSource {
|
|||
}
|
||||
});
|
||||
|
||||
Configs.BIOMES_CONFIG.saveChanges();
|
||||
BiomeAPI.NETHER_BIOME_PICKER.getBiomes().forEach(biome -> biome.updateActualBiomes(biomeRegistry));
|
||||
BiomeAPI.NETHER_BIOME_PICKER.rebuild();
|
||||
|
||||
|
@ -64,8 +66,19 @@ public class BCLibNetherBiomeSource extends BiomeSource {
|
|||
}
|
||||
|
||||
private static List<Biome> getBiomes(Registry<Biome> biomeRegistry) {
|
||||
List<String> include = Configs.BIOMES_CONFIG.getEntry("force_include", "nether_biomes", StringArrayEntry.class).getValue();
|
||||
|
||||
return biomeRegistry.stream().filter(biome -> {
|
||||
ResourceLocation key = biomeRegistry.getKey(biome);
|
||||
|
||||
if (include.contains(key.toString())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GeneratorOptions.addNetherBiomesByCategory() && biome.getBiomeCategory() == BiomeCategory.NETHER) {
|
||||
return true;
|
||||
}
|
||||
|
||||
BCLBiome bclBiome = BiomeAPI.getBiome(key);
|
||||
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
|
||||
if (bclBiome.hasParentBiome()) {
|
||||
|
@ -78,7 +91,7 @@ public class BCLibNetherBiomeSource extends BiomeSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Biome getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.Sampler sampler) {
|
||||
public Biome getBiomeForNoiseGen(int biomeX, int biomeY, int biomeZ) {
|
||||
if ((biomeX & 63) == 0 && (biomeZ & 63) == 0) {
|
||||
biomeMap.clearCache();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package ru.bclib.world.generator;
|
|||
|
||||
import com.google.common.collect.Maps;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.levelgen.LegacyRandomSource;
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
import ru.bclib.noise.OpenSimplexNoise;
|
||||
import ru.bclib.util.MHelper;
|
||||
|
|
|
@ -14,6 +14,8 @@ public class GeneratorOptions {
|
|||
private static boolean farEndBiomes = true;
|
||||
private static boolean customNetherBiomeSource = true;
|
||||
private static boolean customEndBiomeSource = true;
|
||||
private static boolean addNetherBiomesByCategory = false;
|
||||
private static boolean addEndBiomesByCategory = false;
|
||||
|
||||
public static void init() {
|
||||
biomeSizeNether = Configs.GENERATOR_CONFIG.getInt("nether.biomeMap", "biomeSize", 256);
|
||||
|
@ -21,6 +23,8 @@ 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);
|
||||
addNetherBiomesByCategory = Configs.GENERATOR_CONFIG.getBoolean("options", "addNetherBiomesByCategory", false);
|
||||
addEndBiomesByCategory = Configs.GENERATOR_CONFIG.getBoolean("options", "addEndBiomesByCategory", false);
|
||||
}
|
||||
|
||||
public static int getBiomeSizeNether() {
|
||||
|
@ -58,4 +62,12 @@ public class GeneratorOptions {
|
|||
public static boolean customEndBiomeSource() {
|
||||
return customEndBiomeSource;
|
||||
}
|
||||
|
||||
public static boolean addNetherBiomesByCategory() {
|
||||
return addNetherBiomesByCategory;
|
||||
}
|
||||
|
||||
public static boolean addEndBiomesByCategory() {
|
||||
return addEndBiomesByCategory;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ru.bclib.world.structures;
|
||||
|
||||
import net.fabricmc.fabric.api.structure.v1.FabricStructureBuilder;
|
||||
import net.fabricmc.fabric.mixin.structure.FlatChunkGeneratorConfigAccessor;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||
|
@ -24,9 +25,7 @@ public class BCLStructureFeature {
|
|||
.register();
|
||||
this.featureConfigured = this.structure.configured(NoneFeatureConfiguration.NONE);
|
||||
BuiltinRegistries.register(BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE, id, this.featureConfigured);
|
||||
// TODO: (1.18) Find Alternative for this mapping
|
||||
//FlatLevelGeneratorSettings.getStructureToFeatures().put(this.structure, this.featureConfigured);
|
||||
|
||||
FlatChunkGeneratorConfigAccessor.getStructureToFeatures().put(this.structure, this.featureConfigured);
|
||||
}
|
||||
|
||||
public StructureFeature<NoneFeatureConfiguration> getStructure() {
|
||||
|
|
|
@ -5,7 +5,7 @@ import net.minecraft.world.level.biome.Biome;
|
|||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.BlockColumn;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.levelgen.surfacebuilders.ConfiguredSurfaceBuilder;
|
||||
import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilder;
|
||||
import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilderBaseConfiguration;
|
||||
|
@ -43,13 +43,13 @@ public class DoubleBlockSurfaceBuilder extends SurfaceBuilder<SurfaceBuilderBase
|
|||
BlockState stone = Blocks.END_STONE.defaultBlockState();
|
||||
return this.configured(new SurfaceBuilderBaseConfiguration(config1.getTopMaterial(), stone, stone));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void apply(Random random, BlockColumn blockColumn, Biome biome, int x, int z, int height, double noise, BlockState defaultBlock, BlockState defaultFluid, int l, int m, long seed, SurfaceBuilderBaseConfiguration surfaceBuilderConfiguration) {
|
||||
public void apply(Random random, ChunkAccess chunkAccess, Biome biome, int x, int z, int height, double noise, BlockState defaultBlock, BlockState defaultFluid, int l, int m, long seed, SurfaceBuilderBaseConfiguration surfaceBuilderConfiguration) {
|
||||
noise = NOISE.eval(x * 0.1, z * 0.1) + MHelper.randRange(-0.4, 0.4, random);
|
||||
SurfaceBuilder.DEFAULT.apply(
|
||||
random,
|
||||
blockColumn,
|
||||
chunkAccess,
|
||||
biome,
|
||||
x,
|
||||
z,
|
||||
|
|
|
@ -13,14 +13,14 @@
|
|||
"shears.MushroomCowMixin",
|
||||
"shears.SnowGolemMixin",
|
||||
"ComposterBlockAccessor",
|
||||
"InternalBiomeDataMixin",
|
||||
"PotionBrewingAccessor",
|
||||
"RecipeManagerAccessor",
|
||||
"EnchantmentMenuMixin",
|
||||
"MinecraftServerMixin",
|
||||
"PistonBaseBlockMixin",
|
||||
"WorldGenRegionMixin",
|
||||
"DimensionTypeMixin",
|
||||
"TheEndBiomeDataMixin",
|
||||
"NetherBiomeDataMixin",
|
||||
"RecipeManagerMixin",
|
||||
"CraftingMenuMixin",
|
||||
"BoneMealItemMixin",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue