From cf8905ab1a86a4ceec5d5a19741551d6306c393a Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 15 Nov 2021 14:41:46 +0100 Subject: [PATCH 01/48] Added `ComposterAPI` (paulevsGitch/BetterNether#442) --- src/main/java/ru/bclib/api/ComposterAPI.java | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/main/java/ru/bclib/api/ComposterAPI.java diff --git a/src/main/java/ru/bclib/api/ComposterAPI.java b/src/main/java/ru/bclib/api/ComposterAPI.java new file mode 100644 index 00000000..93858cc8 --- /dev/null +++ b/src/main/java/ru/bclib/api/ComposterAPI.java @@ -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; + } +} From 2206674c0dff92d260ef9719497760a75f369a12 Mon Sep 17 00:00:00 2001 From: davidalb97 Date: Thu, 18 Nov 2021 12:22:37 +0000 Subject: [PATCH 02/48] Migrated BetterNether's PR BetterNether/pull/437 into BCLib --- .../common/LayerLightSectionStorageMixin.java | 40 +++++++++++++++++++ src/main/resources/bclib.mixins.common.json | 1 + 2 files changed, 41 insertions(+) create mode 100644 src/main/java/ru/bclib/mixin/common/LayerLightSectionStorageMixin.java diff --git a/src/main/java/ru/bclib/mixin/common/LayerLightSectionStorageMixin.java b/src/main/java/ru/bclib/mixin/common/LayerLightSectionStorageMixin.java new file mode 100644 index 00000000..ac0dc5fa --- /dev/null +++ b/src/main/java/ru/bclib/mixin/common/LayerLightSectionStorageMixin.java @@ -0,0 +1,40 @@ +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 lightFix(long blockPos, CallbackInfoReturnable info) { + try { + long m = SectionPos.blockToSection(blockPos); + DataLayer dataLayer = this.getDataLayer(m, true); + info.setReturnValue( + dataLayer.get( + SectionPos.sectionRelative(BlockPos.getX(blockPos)), + SectionPos.sectionRelative(BlockPos.getY(blockPos)), + SectionPos.sectionRelative(BlockPos.getZ(blockPos)) + ) + ); + info.cancel(); + } catch (Exception e) { + info.setReturnValue(0); + info.cancel(); + } + } + +} diff --git a/src/main/resources/bclib.mixins.common.json b/src/main/resources/bclib.mixins.common.json index 1487977a..2ecb65eb 100644 --- a/src/main/resources/bclib.mixins.common.json +++ b/src/main/resources/bclib.mixins.common.json @@ -20,6 +20,7 @@ "MinecraftServerMixin", "PistonBaseBlockMixin", "WorldGenRegionMixin", + "LayerLightSectionStorageMixin", "DimensionTypeMixin", "RecipeManagerMixin", "CraftingMenuMixin", From 0e80d6609715cef8171f2386af0f0d45227f4692 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Fri, 19 Nov 2021 17:52:41 +0300 Subject: [PATCH 03/48] Fix for #46 --- src/main/java/ru/bclib/api/datafixer/DataFixerAPI.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/ru/bclib/api/datafixer/DataFixerAPI.java b/src/main/java/ru/bclib/api/datafixer/DataFixerAPI.java index b63505c9..d104cbb3 100644 --- a/src/main/java/ru/bclib/api/datafixer/DataFixerAPI.java +++ b/src/main/java/ru/bclib/api/datafixer/DataFixerAPI.java @@ -570,6 +570,9 @@ public class DataFixerAPI { private static List getAllPlayers(File dir) { List 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); From 69d11c0e5a3b0d67ed950614b96c7db202acc491 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Fri, 19 Nov 2021 17:55:34 +0300 Subject: [PATCH 04/48] Small cleanup --- src/main/java/ru/bclib/api/ComposterAPI.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/bclib/api/ComposterAPI.java b/src/main/java/ru/bclib/api/ComposterAPI.java index 93858cc8..ae9eda80 100644 --- a/src/main/java/ru/bclib/api/ComposterAPI.java +++ b/src/main/java/ru/bclib/api/ComposterAPI.java @@ -7,14 +7,14 @@ import ru.bclib.mixin.common.ComposterBlockAccessor; public class ComposterAPI { public static Block allowCompost(float chance, Block block){ - if (block!=null){ + if (block != null) { allowCompost(chance, block.asItem()); } return block; } public static Item allowCompost(float chance, Item item){ - if (item!=null && item != Items.AIR) { + if (item != null && item != Items.AIR) { ComposterBlockAccessor.callAdd(chance, item); } return item; From a2dec40b0a2c0610e2acbd5a77da95abd208ac6f Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sat, 20 Nov 2021 13:41:03 +0300 Subject: [PATCH 05/48] Biome config --- src/main/java/ru/bclib/api/BiomeAPI.java | 11 +++++++++++ src/main/java/ru/bclib/config/Configs.java | 5 ++--- .../java/ru/bclib/world/biomes/BCLBiome.java | 14 ++++++++++++-- .../java/ru/bclib/world/biomes/BCLBiomeDef.java | 16 ++++++++++++++-- .../world/generator/BCLibEndBiomeSource.java | 3 +++ .../world/generator/BCLibNetherBiomeSource.java | 2 ++ 6 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/main/java/ru/bclib/api/BiomeAPI.java b/src/main/java/ru/bclib/api/BiomeAPI.java index 5036f787..eea2dc61 100644 --- a/src/main/java/ru/bclib/api/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/BiomeAPI.java @@ -24,6 +24,7 @@ import net.minecraft.world.level.levelgen.GenerationStep.Decoration; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; import org.jetbrains.annotations.Nullable; +import ru.bclib.config.Configs; import ru.bclib.util.MHelper; import ru.bclib.world.biomes.BCLBiome; import ru.bclib.world.biomes.FabricBiomesData; @@ -85,6 +86,11 @@ public class BiomeAPI { * @return {@link BCLBiome} */ public static BCLBiome registerBiome(BCLBiome biome) { + String biomePath = biome.getID().getNamespace() + "." + biome.getID().getPath(); + if (!Configs.BIOMES_CONFIG.getBoolean(biomePath, "enabled", true)) { + return biome; + } + if (BuiltinRegistries.BIOME.get(biome.getID()) == null) { Registry.register(BuiltinRegistries.BIOME, biome.getID(), biome.getBiome()); } @@ -93,6 +99,11 @@ public class BiomeAPI { } public static BCLBiome registerSubBiome(BCLBiome parent, BCLBiome subBiome) { + String biomePath = subBiome.getID().getNamespace() + "." + subBiome.getID().getPath(); + if (!Configs.BIOMES_CONFIG.getBoolean(biomePath, "enabled", true)) { + return subBiome; + } + registerBiome(subBiome); parent.addSubBiome(subBiome); return subBiome; diff --git a/src/main/java/ru/bclib/config/Configs.java b/src/main/java/ru/bclib/config/Configs.java index 2926b235..d5710c28 100644 --- a/src/main/java/ru/bclib/config/Configs.java +++ b/src/main/java/ru/bclib/config/Configs.java @@ -11,18 +11,17 @@ 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 void save() { MAIN_CONFIG.saveChanges(); RECIPE_CONFIG.saveChanges(); GENERATOR_CONFIG.saveChanges(); + BIOMES_CONFIG.saveChanges(); } } diff --git a/src/main/java/ru/bclib/world/biomes/BCLBiome.java b/src/main/java/ru/bclib/world/biomes/BCLBiome.java index 0cf21cbb..ebdf2a73 100644 --- a/src/main/java/ru/bclib/world/biomes/BCLBiome.java +++ b/src/main/java/ru/bclib/world/biomes/BCLBiome.java @@ -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); diff --git a/src/main/java/ru/bclib/world/biomes/BCLBiomeDef.java b/src/main/java/ru/bclib/world/biomes/BCLBiomeDef.java index 60ced512..1130112b 100644 --- a/src/main/java/ru/bclib/world/biomes/BCLBiomeDef.java +++ b/src/main/java/ru/bclib/world/biomes/BCLBiomeDef.java @@ -32,6 +32,7 @@ import net.minecraft.world.level.levelgen.surfacebuilders.ConfiguredSurfaceBuild import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilder; import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilderBaseConfiguration; import ru.bclib.config.IdConfig; +import ru.bclib.config.PathConfig; import ru.bclib.util.ColorUtil; import ru.bclib.world.features.BCLFeature; import ru.bclib.world.structures.BCLStructureFeature; @@ -113,7 +114,6 @@ public class BCLBiomeDef { /** * Used to load biome settings from config. - * * @param config - {@link IdConfig}. * @return this {@link BCLBiomeDef}. */ @@ -124,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}. */ diff --git a/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java b/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java index d5dd9827..63f212f5 100644 --- a/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java +++ b/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java @@ -14,6 +14,7 @@ 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.Configs; import ru.bclib.noise.OpenSimplexNoise; import ru.bclib.world.biomes.BCLBiome; @@ -62,6 +63,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)); diff --git a/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java b/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java index 27a8ba3c..e8399e4e 100644 --- a/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java +++ b/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java @@ -10,6 +10,7 @@ import net.minecraft.world.level.biome.Biome.BiomeCategory; import net.minecraft.world.level.biome.BiomeSource; import ru.bclib.BCLib; import ru.bclib.api.BiomeAPI; +import ru.bclib.config.Configs; import ru.bclib.world.biomes.BCLBiome; import java.util.LinkedList; @@ -52,6 +53,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(); From 51d484f61eb1dc7d381a7402eb08045dc4546a64 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sat, 20 Nov 2021 13:57:54 +0300 Subject: [PATCH 06/48] Small changes --- src/main/java/ru/bclib/api/BiomeAPI.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/main/java/ru/bclib/api/BiomeAPI.java b/src/main/java/ru/bclib/api/BiomeAPI.java index eea2dc61..5036f787 100644 --- a/src/main/java/ru/bclib/api/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/BiomeAPI.java @@ -24,7 +24,6 @@ import net.minecraft.world.level.levelgen.GenerationStep.Decoration; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; import org.jetbrains.annotations.Nullable; -import ru.bclib.config.Configs; import ru.bclib.util.MHelper; import ru.bclib.world.biomes.BCLBiome; import ru.bclib.world.biomes.FabricBiomesData; @@ -86,11 +85,6 @@ public class BiomeAPI { * @return {@link BCLBiome} */ public static BCLBiome registerBiome(BCLBiome biome) { - String biomePath = biome.getID().getNamespace() + "." + biome.getID().getPath(); - if (!Configs.BIOMES_CONFIG.getBoolean(biomePath, "enabled", true)) { - return biome; - } - if (BuiltinRegistries.BIOME.get(biome.getID()) == null) { Registry.register(BuiltinRegistries.BIOME, biome.getID(), biome.getBiome()); } @@ -99,11 +93,6 @@ public class BiomeAPI { } public static BCLBiome registerSubBiome(BCLBiome parent, BCLBiome subBiome) { - String biomePath = subBiome.getID().getNamespace() + "." + subBiome.getID().getPath(); - if (!Configs.BIOMES_CONFIG.getBoolean(biomePath, "enabled", true)) { - return subBiome; - } - registerBiome(subBiome); parent.addSubBiome(subBiome); return subBiome; From d8c5e84520ec00875033ce35b666b0c446c521e8 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sat, 20 Nov 2021 13:58:35 +0300 Subject: [PATCH 07/48] Version change --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index e3998406..254dfcad 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ loader_version= 0.12.4 fabric_version = 0.41.3+1.17 # Mod Properties -mod_version = 0.5.1 +mod_version = 0.5.2 maven_group = ru.bclib archives_base_name = bclib From c0b7ccca72da07c8bfe16d2d8295615876716287 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sat, 20 Nov 2021 19:01:43 +0300 Subject: [PATCH 08/48] Cleanup --- .../common/LayerLightSectionStorageMixin.java | 45 +++++++++---------- .../SimpleReloadableResourceManagerMixin.java | 2 +- src/main/resources/bclib.mixins.common.json | 2 +- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/main/java/ru/bclib/mixin/common/LayerLightSectionStorageMixin.java b/src/main/java/ru/bclib/mixin/common/LayerLightSectionStorageMixin.java index ac0dc5fa..a222afef 100644 --- a/src/main/java/ru/bclib/mixin/common/LayerLightSectionStorageMixin.java +++ b/src/main/java/ru/bclib/mixin/common/LayerLightSectionStorageMixin.java @@ -12,29 +12,24 @@ 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 lightFix(long blockPos, CallbackInfoReturnable info) { - try { - long m = SectionPos.blockToSection(blockPos); - DataLayer dataLayer = this.getDataLayer(m, true); - info.setReturnValue( - dataLayer.get( - SectionPos.sectionRelative(BlockPos.getX(blockPos)), - SectionPos.sectionRelative(BlockPos.getY(blockPos)), - SectionPos.sectionRelative(BlockPos.getZ(blockPos)) - ) - ); - info.cancel(); - } catch (Exception e) { - info.setReturnValue(0); - info.cancel(); - } - } - + @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 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); + } + } } diff --git a/src/main/java/ru/bclib/mixin/common/SimpleReloadableResourceManagerMixin.java b/src/main/java/ru/bclib/mixin/common/SimpleReloadableResourceManagerMixin.java index 94f5ea2d..d2ff94df 100644 --- a/src/main/java/ru/bclib/mixin/common/SimpleReloadableResourceManagerMixin.java +++ b/src/main/java/ru/bclib/mixin/common/SimpleReloadableResourceManagerMixin.java @@ -26,7 +26,7 @@ public class SimpleReloadableResourceManagerMixin { }; @Inject(method = "hasResource", at = @At("HEAD"), cancellable = true) - private void hasResource(ResourceLocation resourceLocation, CallbackInfoReturnable info) { + private void bclib_hasResource(ResourceLocation resourceLocation, CallbackInfoReturnable info) { if (resourceLocation.getNamespace().equals("minecraft")) { for (String key: BCLIB_MISSING_RESOURCES) { if (resourceLocation.getPath().equals(key)) { diff --git a/src/main/resources/bclib.mixins.common.json b/src/main/resources/bclib.mixins.common.json index 2ecb65eb..e15cb1d5 100644 --- a/src/main/resources/bclib.mixins.common.json +++ b/src/main/resources/bclib.mixins.common.json @@ -6,6 +6,7 @@ "mixins": [ "SimpleReloadableResourceManagerMixin", "shears.DiggingEnchantmentMixin", + "LayerLightSectionStorageMixin", "shears.TripWireBlockMixin", "ChunkBiomeContainerMixin", "shears.BeehiveBlockMixin", @@ -20,7 +21,6 @@ "MinecraftServerMixin", "PistonBaseBlockMixin", "WorldGenRegionMixin", - "LayerLightSectionStorageMixin", "DimensionTypeMixin", "RecipeManagerMixin", "CraftingMenuMixin", From df214cdb24c896a1cddf5750a8e79b3c8c23e3e7 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sat, 20 Nov 2021 20:24:00 +0300 Subject: [PATCH 09/48] Biome include lists --- src/main/java/ru/bclib/config/Config.java | 6 +++--- .../java/ru/bclib/config/ConfigKeeper.java | 21 ++++++++++++------- src/main/java/ru/bclib/config/Configs.java | 12 ++++++++++- src/main/java/ru/bclib/config/PathConfig.java | 1 - .../mixin/common/DimensionTypeMixin.java | 2 +- .../world/generator/BCLibEndBiomeSource.java | 8 +++++++ .../generator/BCLibNetherBiomeSource.java | 8 +++++++ .../world/generator/GeneratorOptions.java | 12 +++++++++++ 8 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/main/java/ru/bclib/config/Config.java b/src/main/java/ru/bclib/config/Config.java index ba2c8afb..a883116e 100644 --- a/src/main/java/ru/bclib/config/Config.java +++ b/src/main/java/ru/bclib/config/Config.java @@ -21,8 +21,8 @@ import java.util.List; import java.util.Map; public abstract class Config { + protected final static Map AUTO_SYNC_CONFIGS = new HashMap<>(); public static final String CONFIG_SYNC_PREFIX = "CONFIG_"; - protected final static Map 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(); } diff --git a/src/main/java/ru/bclib/config/ConfigKeeper.java b/src/main/java/ru/bclib/config/ConfigKeeper.java index f3e6263e..e3711670 100644 --- a/src/main/java/ru/bclib/config/ConfigKeeper.java +++ b/src/main/java/ru/bclib/config/ConfigKeeper.java @@ -23,9 +23,9 @@ import java.util.function.Supplier; public final class ConfigKeeper { private final Map> 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 { - public StringArrayEntry(List 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> extends Entry { - private final Type type; public EnumEntry(T defaultValue) { @@ -372,7 +377,6 @@ public final class ConfigKeeper { } public static abstract class RangeEntry> extends Entry { - 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 { - protected final T defaultValue; protected Consumer writer; protected Supplier reader; @@ -448,5 +451,9 @@ public final class ConfigKeeper { public void setDefault() { this.setValue(defaultValue); } + + protected boolean hasDefaultInName() { + return true; + } } } diff --git a/src/main/java/ru/bclib/config/Configs.java b/src/main/java/ru/bclib/config/Configs.java index d5710c28..deac17d2 100644 --- a/src/main/java/ru/bclib/config/Configs.java +++ b/src/main/java/ru/bclib/config/Configs.java @@ -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 @@ -13,15 +16,22 @@ public class Configs { 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(); } } diff --git a/src/main/java/ru/bclib/config/PathConfig.java b/src/main/java/ru/bclib/config/PathConfig.java index 062e60ec..0bf8d1d3 100644 --- a/src/main/java/ru/bclib/config/PathConfig.java +++ b/src/main/java/ru/bclib/config/PathConfig.java @@ -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); } diff --git a/src/main/java/ru/bclib/mixin/common/DimensionTypeMixin.java b/src/main/java/ru/bclib/mixin/common/DimensionTypeMixin.java index 2826a052..7772d7f9 100644 --- a/src/main/java/ru/bclib/mixin/common/DimensionTypeMixin.java +++ b/src/main/java/ru/bclib/mixin/common/DimensionTypeMixin.java @@ -14,7 +14,7 @@ import ru.bclib.world.generator.BCLibEndBiomeSource; import ru.bclib.world.generator.BCLibNetherBiomeSource; import ru.bclib.world.generator.GeneratorOptions; -@Mixin(value = DimensionType.class, priority = 100) +@Mixin(value = DimensionType.class, priority = 10) public class DimensionTypeMixin { @Inject(method = "defaultNetherGenerator", at = @At("HEAD"), cancellable = true) private static void be_replaceNetherBiomeSource(Registry biomeRegistry, Registry chunkGeneratorSettingsRegistry, long seed, CallbackInfoReturnable info) { diff --git a/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java b/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java index 63f212f5..13d61a76 100644 --- a/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java +++ b/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java @@ -14,6 +14,7 @@ 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; @@ -87,8 +88,15 @@ public class BCLibEndBiomeSource extends BiomeSource { } private static List getBiomes(Registry biomeRegistry) { + List 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; + } + BCLBiome bclBiome = BiomeAPI.getBiome(key); if (bclBiome != BiomeAPI.EMPTY_BIOME) { if (bclBiome.hasParentBiome()) { diff --git a/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java b/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java index e8399e4e..82a981a0 100644 --- a/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java +++ b/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java @@ -10,6 +10,7 @@ import net.minecraft.world.level.biome.Biome.BiomeCategory; import net.minecraft.world.level.biome.BiomeSource; 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; @@ -65,8 +66,15 @@ public class BCLibNetherBiomeSource extends BiomeSource { } private static List getBiomes(Registry biomeRegistry) { + List 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; + } + BCLBiome bclBiome = BiomeAPI.getBiome(key); if (bclBiome != BiomeAPI.EMPTY_BIOME) { if (bclBiome.hasParentBiome()) { diff --git a/src/main/java/ru/bclib/world/generator/GeneratorOptions.java b/src/main/java/ru/bclib/world/generator/GeneratorOptions.java index a2b80ad4..af5c084d 100644 --- a/src/main/java/ru/bclib/world/generator/GeneratorOptions.java +++ b/src/main/java/ru/bclib/world/generator/GeneratorOptions.java @@ -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; + } } From fd0488dd6ae125e36419210947bef6cc38a3b11d Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sat, 20 Nov 2021 20:32:30 +0300 Subject: [PATCH 10/48] Biome by category adding --- .../java/ru/bclib/world/generator/BCLibEndBiomeSource.java | 4 ++++ .../java/ru/bclib/world/generator/BCLibNetherBiomeSource.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java b/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java index 13d61a76..9cc4dc62 100644 --- a/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java +++ b/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java @@ -97,6 +97,10 @@ public class BCLibEndBiomeSource extends BiomeSource { return true; } + if (GeneratorOptions.addEndBiomesByCategory() && biome.getBiomeCategory() == BiomeCategory.THEEND) { + return true; + } + BCLBiome bclBiome = BiomeAPI.getBiome(key); if (bclBiome != BiomeAPI.EMPTY_BIOME) { if (bclBiome.hasParentBiome()) { diff --git a/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java b/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java index 82a981a0..6f26a475 100644 --- a/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java +++ b/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java @@ -75,6 +75,10 @@ public class BCLibNetherBiomeSource extends BiomeSource { return true; } + if (GeneratorOptions.addNetherBiomesByCategory() && biome.getBiomeCategory() == BiomeCategory.NETHER) { + return true; + } + BCLBiome bclBiome = BiomeAPI.getBiome(key); if (bclBiome != BiomeAPI.EMPTY_BIOME) { if (bclBiome.hasParentBiome()) { From 2969680b13decff2911ff58af38687a3501bc3d1 Mon Sep 17 00:00:00 2001 From: "E. Kim" Date: Mon, 22 Nov 2021 13:01:11 +0900 Subject: [PATCH 11/48] Create ko_kr.json --- .../resources/assets/bclib/lang/ko_kr.json | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/main/resources/assets/bclib/lang/ko_kr.json diff --git a/src/main/resources/assets/bclib/lang/ko_kr.json b/src/main/resources/assets/bclib/lang/ko_kr.json new file mode 100644 index 00000000..dddcd4f9 --- /dev/null +++ b/src/main/resources/assets/bclib/lang/ko_kr.json @@ -0,0 +1,50 @@ +{ + "message.bclib.anvil_damage": "§c위험", + "bclib.datafixer.backupWarning.title": "가디언에서 호환되지 않는 월드를 감지", + "bclib.datafixer.backupWarning.message": "가디언에서 감지한 바에 따르면 설치된 모드들의 내부가 이 월드가 마지막으로 게임한 이후로 바뀌었습니다.\n\n우리는 당신을 위해 자동으로 월드를 바꿀 수 있습니다. 변경 내용을 적용하지 않고 계속하면 월드 로드가 올바르게 수행되지 않을 수 있습니다. 계속하기 전에 백업을 만들어야 합니다.", + "bclib.datafixer.backupWarning.backup": "수정 사항을 적용하기 전에 백업 생성", + "bclib.datafixer.backupWarning.nofixes": "수정 없이 계속", + "bclib.datafixer.backupWarning.fix": "수정 사항 적용", + "title.bclib.bclibmissmatch": "버전 불일치", + "message.bclib.bclibmissmatch": "서버와 클라이언트의 BCLib 버전이 일치하지 않습니다. 이것은 게임을 할 때 문제를 일으킬 것입니다.\n\n서버에서 BCLib-Version을 자동으로 다운로드하시겠습니까? \n\nBCLib은 새 버전을 설치하기 전에 이전 버전을 모드 폴더의 하위 디렉터리로 이동합니다.", + "title.bclib.syncfiles": "데이터 불일치", + "message.bclib.syncfiles": "서버의 일부 내용이 클라이언트의 버전과 일치하지 않습니다.\n선택한 내용을 서버의 데이터로 바꾸시겠습니까?", + "message.bclib.syncfiles.mods": "모드 동기화", + "message.bclib.syncfiles.configs": "구성 동기화", + "message.bclib.syncfiles.folders": "폴더 및 파일 동기화", + "message.bclib.syncfiles.delete": "필요 없는 삭제", + "title.bclib.confirmrestart": "재시작 필요", + "message.bclib.confirmrestart": "요청한 콘텐츠가 동기화되었습니다. 지금 마인크래프트를 다시 시작해야 합니다.", + "title.link.bclib.discord": "디스코드", + "title.bclib.modmenu.main": "BCLib 환경설정", + "title.bclib.progress": "진행", + "title.bclib.filesync.progress": "파일 전송", + "message.bclib.filesync.progress": "파일 내용을 서버와 동기화하는 중", + "message.bclib.filesync.progress.stage.empty": "", + + "title.config.bclib.client.auto_sync.enabled": "자동 동기화 사용", + "title.config.bclib.client.auto_sync.acceptConfigs": "들어오는 구성 파일 수락", + "title.config.bclib.client.auto_sync.acceptFiles": "수신 파일 수락", + "title.config.bclib.client.auto_sync.acceptMods": "수신 모드 수락", + "title.config.bclib.client.auto_sync.displayModInfo": "서버사이드 모드가 클라이언트와 다를 때 경고 표시", + "title.config.bclib.client.auto_sync.debugHashes": "로그에 자동 동기화 디버그 해시 인쇄", + + "title.bclib.syncfiles.modInfo": "모드 정보", + "title.bclib.syncfiles.modlist": "모드 목록", + "message.bclib.syncfiles.modlist": "설치된 모드의 상태는 다음과 같습니다.\n\n로컬에 없거나 서버에 다른 버전이 있는 모든 모드는 동기화됩니다.", + "title.bclib.modmissmatch": "모드 버전 충돌", + "message.bclib.modmissmatch": "이 클라이언트의 일부 모드는 서버의 모드 버전과 일치하지 않습니다.\n\n모드가 일치하지 않으면 이상한 게임 동작이나 충돌이 발생할 수 있습니다. 서버와 같은 모드를 사용하는 것으로 해주세요.", + + "message.bclib.datafixer.progress.waitbackup": "백업이 완료될 때까지 기다리는 중입니다. 시간이 걸릴 수 있습니다!", + "message.bclib.datafixer.progress.reading": "데이터 읽기", + "message.bclib.datafixer.progress.players": "플레이어 수정", + "message.bclib.datafixer.progress.level": "level.dat에 패치 적용", + "message.bclib.datafixer.progress.worlddata": "사용자 지정 월드-데이터 패치 적용", + "message.bclib.datafixer.progress.regions": "모든 영역 복구", + "message.bclib.datafixer.progress.saving": "패치 상태 저장 중", + "title.bclib.datafixer.progress": "월드 수정", + "message.bclib.datafixer.progress": "사용자 환경에 모든 패치를 적용하고 있습니다.", + "title.bclib.datafixer.error": "월드를 수정하는 중 오류 발생", + "message.bclib.datafixer.error": "월드를 수리하는 동안 오류가 발생했습니다. 즉, 이 수준은 일치하지 않는 상태이므로 재생하지 않아야 합니다. 백업을 복구하고 아래 오류를 수정한 후 다시 시도하십시오.", + "title.bclib.datafixer.error.continue": "계속 진행 및 수정됨" +} From fc3dc71a44fc239cbb4b4cb2f933667a16f85929 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Mon, 22 Nov 2021 17:15:33 +0300 Subject: [PATCH 12/48] Feature array length fix --- gradle.properties | 2 +- src/main/java/ru/bclib/api/BiomeAPI.java | 34 ++++++++++++++---------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/gradle.properties b/gradle.properties index 254dfcad..372a5718 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ loader_version= 0.12.4 fabric_version = 0.41.3+1.17 # Mod Properties -mod_version = 0.5.2 +mod_version = 0.5.3 maven_group = ru.bclib archives_base_name = bclib diff --git a/src/main/java/ru/bclib/api/BiomeAPI.java b/src/main/java/ru/bclib/api/BiomeAPI.java index 5036f787..f8c1d1f4 100644 --- a/src/main/java/ru/bclib/api/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/BiomeAPI.java @@ -414,13 +414,7 @@ public class BiomeAPI { public static void addBiomeFeature(Biome biome, ConfiguredFeature feature, Decoration step) { GenerationSettingsAccessor accessor = (GenerationSettingsAccessor) biome.getGenerationSettings(); List>>> 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>> list = getMutableList(biomeFeatures.get(index)); + List>> list = getList(step, biomeFeatures); list.add(() -> feature); accessor.fabric_setFeatures(biomeFeatures); } @@ -434,18 +428,30 @@ public class BiomeAPI { GenerationSettingsAccessor accessor = (GenerationSettingsAccessor) biome.getGenerationSettings(); List>>> 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>> list = getMutableList(biomeFeatures.get(index)); + List>> 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>> getList(Decoration step, List>>> lists) { + int index = step.ordinal(); + if (lists.size() <= index) { + for (int i = lists.size(); i <= index; i++) { + lists.add(Lists.newArrayList()); + } + } + List>> 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. From 8d9a95da7a7b0d976c84cd4d36d2fa0ba2865035 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 26 Nov 2021 14:29:48 +0100 Subject: [PATCH 13/48] Be more tolerant against reading issues --- src/main/java/ru/bclib/api/datafixer/DataFixerAPI.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/bclib/api/datafixer/DataFixerAPI.java b/src/main/java/ru/bclib/api/datafixer/DataFixerAPI.java index d104cbb3..1a832f6f 100644 --- a/src/main/java/ru/bclib/api/datafixer/DataFixerAPI.java +++ b/src/main/java/ru/bclib/api/datafixer/DataFixerAPI.java @@ -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; @@ -607,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); } } From 53080bea06daddef5d1776be08568ef20770c838 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 26 Nov 2021 16:22:32 +0100 Subject: [PATCH 14/48] new `SpawnAPI` --- src/main/java/ru/bclib/api/SpawnAPI.java | 126 +++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/main/java/ru/bclib/api/SpawnAPI.java diff --git a/src/main/java/ru/bclib/api/SpawnAPI.java b/src/main/java/ru/bclib/api/SpawnAPI.java new file mode 100644 index 00000000..dff43bdb --- /dev/null +++ b/src/main/java/ru/bclib/api/SpawnAPI.java @@ -0,0 +1,126 @@ +package ru.bclib.api; + +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.MobSpawnType; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; +import ru.bclib.util.BlocksHelper; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + + +public class SpawnAPI { + @FunctionalInterface + public interface SpawnRule { + boolean test(EntityType type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random); + } + + public interface IsBlock{ + boolean is(BlockState state); + } + + private Class entityClass; + public SpawnAPI(Class entityClass){ + this.entityClass = entityClass; + } + + ArrayList> rules = new ArrayList<>(); + + public SpawnAPI notPeaceful() { + rules.add((type, world, spawnReason, pos, random) -> world.getDifficulty() != Difficulty.PEACEFUL); + return this; + } + + public SpawnAPI notPeacefulBelowBrightness() { + return notPeacefulBelowBrightness(7); + } + + public SpawnAPI notPeacefulBelowBrightness(int bright) { + rules.add((type, world, spawnReason, pos, random) -> world.getDifficulty() != Difficulty.PEACEFUL && world.getMaxLocalRawBrightness(pos) <= bright); + return this; + } + + public SpawnAPI belowBrightness() { + return belowBrightness(7); + } + + public SpawnAPI belowBrightness(int bright) { + rules.add((type, world, spawnReason, pos, random) -> world.getMaxLocalRawBrightness(pos) <= bright); + return this; + } + + public SpawnAPI belowMinHeight() { + rules.add((type, world, spawnReason, pos, random) -> pos.getY() < world.dimensionType().minY()); + return this; + } + + public SpawnAPI maxAlive(){ + return maxAlive(4, 256); + } + + public SpawnAPI maxAlive(int count){ + return maxAlive(count, 256); + } + + public SpawnAPI maxAlive(int count, int size){ + rules.add((type, world, spawnReason, pos, random) -> { + try { + final AABB box = new AABB(pos).inflate(size, 256, size); + final List list = world.getEntitiesOfClass(entityClass, box, (entity) -> true); + return list.size() < count; + } + catch (Exception e) { + return true; + } + }); + return this; + } + + public SpawnAPI maxHeight(int height) { + rules.add((type, world, spawnReason, pos, random) -> { + int h = BlocksHelper.downRay(world, pos, height+1); + return h<=height; + }); + return this; + } + + public SpawnAPI notAboveBlock(IsBlock blockTest, int height) { + rules.add((type, world, spawnReason, pos, random) -> { + int h = BlocksHelper.downRay(world, pos, height+1); + if (h>height) return false; + + for (int i = 1; i <= h; i++) + if (blockTest.is(world.getBlockState(pos.below(i)))) + return false; + + return true; + }); + return this; + } + + public SpawnAPI aboveBlock(IsBlock blockTest, int height) { + rules.add((type, world, spawnReason, pos, random) -> { + int h = BlocksHelper.downRay(world, pos, height+1); + if (h>height) return false; + + for (int i = 1; i <= h; i++) + if (blockTest.is(world.getBlockState(pos.below(i)))) + return true; + + return false; + }); + return this; + } + + public boolean canSpawn(EntityType type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random) { + return rules.stream() + .map(r -> r.test(type, world, spawnReason, pos, random)) + .reduce(true, (p, c) -> p && c); + } +} From 16484d18b25dc82132e9d2afac95bc79e1ad9725 Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 27 Nov 2021 01:01:19 +0100 Subject: [PATCH 15/48] Fix for height restrictions --- src/main/java/ru/bclib/api/SpawnAPI.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/bclib/api/SpawnAPI.java b/src/main/java/ru/bclib/api/SpawnAPI.java index dff43bdb..1ce39ab1 100644 --- a/src/main/java/ru/bclib/api/SpawnAPI.java +++ b/src/main/java/ru/bclib/api/SpawnAPI.java @@ -55,8 +55,8 @@ public class SpawnAPI { return this; } - public SpawnAPI belowMinHeight() { - rules.add((type, world, spawnReason, pos, random) -> pos.getY() < world.dimensionType().minY()); + public SpawnAPI belowMaxHeight() { + rules.add((type, world, spawnReason, pos, random) -> pos.getY() >= world.dimensionType().logicalHeight()); return this; } From 5d5c215f48f323e96e28d9019498c36bfd55198f Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 27 Nov 2021 02:11:32 +0100 Subject: [PATCH 16/48] Version update --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 372a5718..e12f8ad5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ loader_version= 0.12.4 fabric_version = 0.41.3+1.17 # Mod Properties -mod_version = 0.5.3 +mod_version = 0.5.4 maven_group = ru.bclib archives_base_name = bclib From 7def63ee018663e6f3e936dd6935f3fb02236e33 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 05:45:53 +0300 Subject: [PATCH 17/48] Spawn API enhancements --- src/main/java/ru/bclib/BCLibPatch.java | 2 +- src/main/java/ru/bclib/api/SpawnAPI.java | 2 +- .../bclib/api/datafixer/ForcedLevelPatch.java | 2 + .../bclib/api/datafixer/MigrationProfile.java | 2 + .../java/ru/bclib/api/datafixer/Patch.java | 2 + .../bclib/api/spawning/SpawnRuleBulder.java | 215 ++++++++++++++++++ .../ru/bclib/api/spawning/SpawnRuleEntry.java | 30 +++ .../PatchBiFunction.java | 5 +- .../PatchFunction.java | 5 +- .../java/ru/bclib/interfaces/SpawnRule.java | 14 ++ src/main/resources/bclib.mixins.client.json | 14 +- src/main/resources/bclib.mixins.common.json | 52 ++--- 12 files changed, 308 insertions(+), 37 deletions(-) create mode 100644 src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java create mode 100644 src/main/java/ru/bclib/api/spawning/SpawnRuleEntry.java rename src/main/java/ru/bclib/{api/datafixer => interfaces}/PatchBiFunction.java (52%) rename src/main/java/ru/bclib/{api/datafixer => interfaces}/PatchFunction.java (50%) create mode 100644 src/main/java/ru/bclib/interfaces/SpawnRule.java diff --git a/src/main/java/ru/bclib/BCLibPatch.java b/src/main/java/ru/bclib/BCLibPatch.java index d7db7d40..44e4bc51 100644 --- a/src/main/java/ru/bclib/BCLibPatch.java +++ b/src/main/java/ru/bclib/BCLibPatch.java @@ -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; diff --git a/src/main/java/ru/bclib/api/SpawnAPI.java b/src/main/java/ru/bclib/api/SpawnAPI.java index 1ce39ab1..1493ca99 100644 --- a/src/main/java/ru/bclib/api/SpawnAPI.java +++ b/src/main/java/ru/bclib/api/SpawnAPI.java @@ -14,7 +14,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; - +@Deprecated(forRemoval = true) public class SpawnAPI { @FunctionalInterface public interface SpawnRule { diff --git a/src/main/java/ru/bclib/api/datafixer/ForcedLevelPatch.java b/src/main/java/ru/bclib/api/datafixer/ForcedLevelPatch.java index 34951454..333d473b 100644 --- a/src/main/java/ru/bclib/api/datafixer/ForcedLevelPatch.java +++ b/src/main/java/ru/bclib/api/datafixer/ForcedLevelPatch.java @@ -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; diff --git a/src/main/java/ru/bclib/api/datafixer/MigrationProfile.java b/src/main/java/ru/bclib/api/datafixer/MigrationProfile.java index 26065093..831470ff 100644 --- a/src/main/java/ru/bclib/api/datafixer/MigrationProfile.java +++ b/src/main/java/ru/bclib/api/datafixer/MigrationProfile.java @@ -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; diff --git a/src/main/java/ru/bclib/api/datafixer/Patch.java b/src/main/java/ru/bclib/api/datafixer/Patch.java index bc64e3c5..30a26ce7 100644 --- a/src/main/java/ru/bclib/api/datafixer/Patch.java +++ b/src/main/java/ru/bclib/api/datafixer/Patch.java @@ -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; diff --git a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java new file mode 100644 index 00000000..92c35ce9 --- /dev/null +++ b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java @@ -0,0 +1,215 @@ +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.MobSpawnType; +import net.minecraft.world.entity.SpawnPlacements.SpawnPredicate; +import net.minecraft.world.entity.SpawnPlacements.Type; +import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.levelgen.Heightmap.Types; +import net.minecraft.world.phys.AABB; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.function.Supplier; + +public class SpawnRuleBulder { + private static final Map RULES_CACHE = Maps.newHashMap(); + private static final SpawnRuleBulder INSTANCE = new SpawnRuleBulder(); + private List rules = Lists.newArrayList(); + private SpawnRuleEntry entryInstance; + private EntityType entityType; + + private SpawnRuleBulder() {} + + /** + * Starts new rule building process. + * @return prepared {@link SpawnRuleBulder} instance + */ + public static SpawnRuleBulder start(EntityType entityType) { + INSTANCE.entityType = entityType; + INSTANCE.rules.clear(); + return INSTANCE; + } + + /** + * Stop entity spawn on peaceful {@link Difficulty} + * @return same {@link SpawnRuleBulder} instance + */ + public SpawnRuleBulder 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 below world logical height (useful for Nether mobs). + * @return same {@link SpawnRuleBulder} instance + */ + public SpawnRuleBulder belowMaxHeight() { + entryInstance = getFromCache("not_peaceful", () -> { + return new SpawnRuleEntry(0, (type, world, spawnReason, pos, random) -> pos.getY() < world.dimensionType().logicalHeight()); + }); + rules.add(entryInstance); + return this; + } + + /** + * Will spawn entity only below specified brightness value. + * @param lightLevel light level upper limit. + * @return same {@link SpawnRuleBulder} instance + */ + public SpawnRuleBulder belowBrightness(int lightLevel) { + entryInstance = getFromCache("below_brightness_" + lightLevel, () -> { + return new SpawnRuleEntry(1, (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 SpawnRuleBulder} instance + */ + public SpawnRuleBulder aboveBrightness(int lightLevel) { + entryInstance = getFromCache("above_brightness_" + lightLevel, () -> { + return new SpawnRuleEntry(1, (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. + * @return same {@link SpawnRuleBulder} instance + */ + public SpawnRuleBulder vanillaHostile() { + return notPeaceful().belowBrightness(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 SpawnRuleBulder} instance + */ + public SpawnRuleBulder maxNerby(EntityType selectorType, int count, int side) { + final Class baseClass = selectorType.getBaseClass(); + entryInstance = getFromCache("below_brightness_" + selectorType.getDescriptionId(), () -> { + return new SpawnRuleEntry(2, (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 SpawnRuleBulder} instance + */ + public SpawnRuleBulder maxNerby(int count, int side) { + return maxNerby(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 SpawnRuleBulder} instance + */ + public SpawnRuleBulder maxNerby(int count) { + return maxNerby(entityType, count, 256); + } + + /** + * 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 rulesCopy = Lists.newArrayList(this.rules); + Collections.sort(rulesCopy); + + SpawnPredicate predicate = new SpawnPredicate() { + @Override + public boolean test(EntityType entityType, ServerLevelAccessor serverLevelAccessor, MobSpawnType mobSpawnType, BlockPos blockPos, Random 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 supplier) { + SpawnRuleEntry entry = RULES_CACHE.get(name); + if (entry == null) { + entry = supplier.get(); + RULES_CACHE.put(name, entry); + } + return entry; + } +} diff --git a/src/main/java/ru/bclib/api/spawning/SpawnRuleEntry.java b/src/main/java/ru/bclib/api/spawning/SpawnRuleEntry.java new file mode 100644 index 00000000..710860c6 --- /dev/null +++ b/src/main/java/ru/bclib/api/spawning/SpawnRuleEntry.java @@ -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 implements Comparable { + private final SpawnRule rule; + private final byte priority; + + public SpawnRuleEntry(int priority, SpawnRule rule) { + this.priority = (byte) priority; + this.rule = rule; + } + + boolean canSpawn(EntityType 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); + } +} diff --git a/src/main/java/ru/bclib/api/datafixer/PatchBiFunction.java b/src/main/java/ru/bclib/interfaces/PatchBiFunction.java similarity index 52% rename from src/main/java/ru/bclib/api/datafixer/PatchBiFunction.java rename to src/main/java/ru/bclib/interfaces/PatchBiFunction.java index 6bd8da12..4bb345af 100644 --- a/src/main/java/ru/bclib/api/datafixer/PatchBiFunction.java +++ b/src/main/java/ru/bclib/interfaces/PatchBiFunction.java @@ -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 { diff --git a/src/main/java/ru/bclib/api/datafixer/PatchFunction.java b/src/main/java/ru/bclib/interfaces/PatchFunction.java similarity index 50% rename from src/main/java/ru/bclib/api/datafixer/PatchFunction.java rename to src/main/java/ru/bclib/interfaces/PatchFunction.java index 7d429d68..809d55e0 100644 --- a/src/main/java/ru/bclib/api/datafixer/PatchFunction.java +++ b/src/main/java/ru/bclib/interfaces/PatchFunction.java @@ -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 { diff --git a/src/main/java/ru/bclib/interfaces/SpawnRule.java b/src/main/java/ru/bclib/interfaces/SpawnRule.java new file mode 100644 index 00000000..8dffc463 --- /dev/null +++ b/src/main/java/ru/bclib/interfaces/SpawnRule.java @@ -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 { + boolean canSpawn(EntityType type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random); +} diff --git a/src/main/resources/bclib.mixins.client.json b/src/main/resources/bclib.mixins.client.json index b3aebf4a..3d87e139 100644 --- a/src/main/resources/bclib.mixins.client.json +++ b/src/main/resources/bclib.mixins.client.json @@ -4,16 +4,16 @@ "package": "ru.bclib.mixin.client", "compatibilityLevel": "JAVA_16", "client": [ - "SimpleReloadableResourceManagerMixin", - "EnchantingTableBlockMixin", + "AnvilScreenMixin", "BackgroundRendererMixin", "ClientRecipeBookMixin", - "ModelManagerMixin", - "TextureAtlasMixin", - "AnvilScreenMixin", - "ModelBakeryMixin", + "EnchantingTableBlockMixin", + "GameMixin", "MinecraftMixin", - "GameMixin" + "ModelBakeryMixin", + "ModelManagerMixin", + "SimpleReloadableResourceManagerMixin", + "TextureAtlasMixin" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/resources/bclib.mixins.common.json b/src/main/resources/bclib.mixins.common.json index e15cb1d5..3f39c3ef 100644 --- a/src/main/resources/bclib.mixins.common.json +++ b/src/main/resources/bclib.mixins.common.json @@ -4,35 +4,35 @@ "package": "ru.bclib.mixin.common", "compatibilityLevel": "JAVA_16", "mixins": [ - "SimpleReloadableResourceManagerMixin", - "shears.DiggingEnchantmentMixin", - "LayerLightSectionStorageMixin", - "shears.TripWireBlockMixin", - "ChunkBiomeContainerMixin", - "shears.BeehiveBlockMixin", - "shears.PumpkinBlockMixin", - "shears.MushroomCowMixin", - "shears.SnowGolemMixin", - "ComposterBlockAccessor", - "InternalBiomeDataMixin", - "PotionBrewingAccessor", - "RecipeManagerAccessor", - "EnchantmentMenuMixin", - "MinecraftServerMixin", - "PistonBaseBlockMixin", - "WorldGenRegionMixin", - "DimensionTypeMixin", - "RecipeManagerMixin", - "CraftingMenuMixin", - "BoneMealItemMixin", - "shears.SheepMixin", - "PortalShapeMixin", - "ServerLevelMixin", "AnvilBlockMixin", "AnvilMenuMixin", - "TagLoaderMixin", "BiomeMixin", - "MainMixin" + "BoneMealItemMixin", + "ChunkBiomeContainerMixin", + "ComposterBlockAccessor", + "CraftingMenuMixin", + "DimensionTypeMixin", + "EnchantmentMenuMixin", + "InternalBiomeDataMixin", + "LayerLightSectionStorageMixin", + "MainMixin", + "MinecraftServerMixin", + "PistonBaseBlockMixin", + "PortalShapeMixin", + "PotionBrewingAccessor", + "RecipeManagerAccessor", + "RecipeManagerMixin", + "ServerLevelMixin", + "SimpleReloadableResourceManagerMixin", + "TagLoaderMixin", + "WorldGenRegionMixin", + "shears.BeehiveBlockMixin", + "shears.DiggingEnchantmentMixin", + "shears.MushroomCowMixin", + "shears.PumpkinBlockMixin", + "shears.SheepMixin", + "shears.SnowGolemMixin", + "shears.TripWireBlockMixin" ], "injectors": { "defaultRequire": 1 From 65d9d7f2cee81d4af322c8284f6ee3aff04d8b15 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 05:53:07 +0300 Subject: [PATCH 18/48] Small fixes --- .../bclib/api/spawning/SpawnRuleBulder.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java index 92c35ce9..19900841 100644 --- a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java +++ b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java @@ -92,10 +92,19 @@ public class SpawnRuleBulder { /** * 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 SpawnRuleBulder} instance + */ + public SpawnRuleBulder 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 SpawnRuleBulder} instance */ public SpawnRuleBulder vanillaHostile() { - return notPeaceful().belowBrightness(7); + return hostile(7); } /** @@ -105,7 +114,7 @@ public class SpawnRuleBulder { * @param side side of box to search in. * @return same {@link SpawnRuleBulder} instance */ - public SpawnRuleBulder maxNerby(EntityType selectorType, int count, int side) { + public SpawnRuleBulder maxNearby(EntityType selectorType, int count, int side) { final Class baseClass = selectorType.getBaseClass(); entryInstance = getFromCache("below_brightness_" + selectorType.getDescriptionId(), () -> { return new SpawnRuleEntry(2, (type, world, spawnReason, pos, random) -> { @@ -129,8 +138,8 @@ public class SpawnRuleBulder { * @param side side of box to search in. * @return same {@link SpawnRuleBulder} instance */ - public SpawnRuleBulder maxNerby(int count, int side) { - return maxNerby(entityType, count, side); + public SpawnRuleBulder maxNearby(int count, int side) { + return maxNearby(entityType, count, side); } /** @@ -138,8 +147,8 @@ public class SpawnRuleBulder { * @param count max entity count. * @return same {@link SpawnRuleBulder} instance */ - public SpawnRuleBulder maxNerby(int count) { - return maxNerby(entityType, count, 256); + public SpawnRuleBulder maxNearby(int count) { + return maxNearby(entityType, count, 256); } /** From 6cbd4006360f65664bb8d6b9270048982aafd4fc Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 05:55:45 +0300 Subject: [PATCH 19/48] Lambda replacement --- .../java/ru/bclib/api/spawning/SpawnRuleBulder.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java index 19900841..3c2eb294 100644 --- a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java +++ b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java @@ -160,16 +160,13 @@ public class SpawnRuleBulder { final List rulesCopy = Lists.newArrayList(this.rules); Collections.sort(rulesCopy); - SpawnPredicate predicate = new SpawnPredicate() { - @Override - public boolean test(EntityType entityType, ServerLevelAccessor serverLevelAccessor, MobSpawnType mobSpawnType, BlockPos blockPos, Random random) { - for (SpawnRuleEntry rule: rulesCopy) { - if (!rule.canSpawn(entityType, serverLevelAccessor, mobSpawnType, blockPos, random)) { - return false; - } + SpawnPredicate predicate = (entityType, serverLevelAccessor, mobSpawnType, blockPos, random) -> { + for (SpawnRuleEntry rule: rulesCopy) { + if (!rule.canSpawn(entityType, serverLevelAccessor, mobSpawnType, blockPos, random)) { + return false; } - return true; } + return true; }; SpawnRestrictionAccessor.callRegister(entityType, spawnType, heightmapType, predicate); From 3c5d5609811107418025a733b332ea3280d18241 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 06:02:46 +0300 Subject: [PATCH 20/48] Height spawn limit --- .../bclib/api/spawning/SpawnRuleBulder.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java index 3c2eb294..8d1d74d9 100644 --- a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java +++ b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java @@ -52,12 +52,30 @@ public class SpawnRuleBulder { return this; } + /** + * Restricts entity spawn above world surface (flying mobs). + * @param minHeight minimal spawn height. + * @return same {@link SpawnRuleBulder} instance + */ + public SpawnRuleBulder 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 SpawnRuleBulder} instance */ public SpawnRuleBulder belowMaxHeight() { - entryInstance = getFromCache("not_peaceful", () -> { + entryInstance = getFromCache("below_max_height", () -> { return new SpawnRuleEntry(0, (type, world, spawnReason, pos, random) -> pos.getY() < world.dimensionType().logicalHeight()); }); rules.add(entryInstance); From 45216cdab5875d9d0bab4c837fb2faf5f6a20e76 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 06:03:12 +0300 Subject: [PATCH 21/48] Name fix --- src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java index 8d1d74d9..5db87b52 100644 --- a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java +++ b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java @@ -134,7 +134,7 @@ public class SpawnRuleBulder { */ public SpawnRuleBulder maxNearby(EntityType selectorType, int count, int side) { final Class baseClass = selectorType.getBaseClass(); - entryInstance = getFromCache("below_brightness_" + selectorType.getDescriptionId(), () -> { + entryInstance = getFromCache("max_nearby_" + selectorType.getDescriptionId(), () -> { return new SpawnRuleEntry(2, (type, world, spawnReason, pos, random) -> { try { final AABB box = new AABB(pos).inflate(side, world.getHeight(), side); From e0443a7a13d1583cf15a5ca93251e0c9581df489 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 06:12:05 +0300 Subject: [PATCH 22/48] Chance spawning rule --- .../bclib/api/spawning/SpawnRuleBulder.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java index 5db87b52..4d040412 100644 --- a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java +++ b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java @@ -82,6 +82,19 @@ public class SpawnRuleBulder { return this; } + /** + * Will spawn entity with 1 / chance probability (randomly). + * @param chance probability limit. + * @return same {@link SpawnRuleBulder} instance + */ + public SpawnRuleBulder 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. @@ -89,7 +102,7 @@ public class SpawnRuleBulder { */ public SpawnRuleBulder belowBrightness(int lightLevel) { entryInstance = getFromCache("below_brightness_" + lightLevel, () -> { - return new SpawnRuleEntry(1, (type, world, spawnReason, pos, random) -> world.getMaxLocalRawBrightness(pos) <= lightLevel); + return new SpawnRuleEntry(2, (type, world, spawnReason, pos, random) -> world.getMaxLocalRawBrightness(pos) <= lightLevel); }); rules.add(entryInstance); return this; @@ -102,7 +115,7 @@ public class SpawnRuleBulder { */ public SpawnRuleBulder aboveBrightness(int lightLevel) { entryInstance = getFromCache("above_brightness_" + lightLevel, () -> { - return new SpawnRuleEntry(1, (type, world, spawnReason, pos, random) -> world.getMaxLocalRawBrightness(pos) >= lightLevel); + return new SpawnRuleEntry(2, (type, world, spawnReason, pos, random) -> world.getMaxLocalRawBrightness(pos) >= lightLevel); }); rules.add(entryInstance); return this; @@ -135,7 +148,7 @@ public class SpawnRuleBulder { public SpawnRuleBulder maxNearby(EntityType selectorType, int count, int side) { final Class baseClass = selectorType.getBaseClass(); entryInstance = getFromCache("max_nearby_" + selectorType.getDescriptionId(), () -> { - return new SpawnRuleEntry(2, (type, world, spawnReason, pos, random) -> { + 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); From 8439528e8ec278514fa65d45f5dfebcc16e001cd Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 06:16:52 +0300 Subject: [PATCH 23/48] Custom spawning rule --- .../bclib/api/spawning/SpawnRuleBulder.java | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java index 4d040412..27819b2c 100644 --- a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java +++ b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java @@ -14,6 +14,7 @@ import net.minecraft.world.entity.SpawnPlacements.Type; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.levelgen.Heightmap.Types; import net.minecraft.world.phys.AABB; +import ru.bclib.interfaces.SpawnRule; import java.util.Collections; import java.util.List; @@ -32,7 +33,7 @@ public class SpawnRuleBulder { /** * Starts new rule building process. - * @return prepared {@link SpawnRuleBulder} instance + * @return prepared {@link SpawnRuleBulder} instance. */ public static SpawnRuleBulder start(EntityType entityType) { INSTANCE.entityType = entityType; @@ -42,7 +43,7 @@ public class SpawnRuleBulder { /** * Stop entity spawn on peaceful {@link Difficulty} - * @return same {@link SpawnRuleBulder} instance + * @return same {@link SpawnRuleBulder} instance. */ public SpawnRuleBulder notPeaceful() { entryInstance = getFromCache("not_peaceful", () -> { @@ -55,7 +56,7 @@ public class SpawnRuleBulder { /** * Restricts entity spawn above world surface (flying mobs). * @param minHeight minimal spawn height. - * @return same {@link SpawnRuleBulder} instance + * @return same {@link SpawnRuleBulder} instance. */ public SpawnRuleBulder aboveGround(int minHeight) { entryInstance = getFromCache("above_ground", () -> { @@ -72,7 +73,7 @@ public class SpawnRuleBulder { /** * Restricts entity spawn below world logical height (useful for Nether mobs). - * @return same {@link SpawnRuleBulder} instance + * @return same {@link SpawnRuleBulder} instance. */ public SpawnRuleBulder belowMaxHeight() { entryInstance = getFromCache("below_max_height", () -> { @@ -85,7 +86,7 @@ public class SpawnRuleBulder { /** * Will spawn entity with 1 / chance probability (randomly). * @param chance probability limit. - * @return same {@link SpawnRuleBulder} instance + * @return same {@link SpawnRuleBulder} instance. */ public SpawnRuleBulder withChance(int chance) { entryInstance = getFromCache("with_chance_" + chance, () -> { @@ -98,7 +99,7 @@ public class SpawnRuleBulder { /** * Will spawn entity only below specified brightness value. * @param lightLevel light level upper limit. - * @return same {@link SpawnRuleBulder} instance + * @return same {@link SpawnRuleBulder} instance. */ public SpawnRuleBulder belowBrightness(int lightLevel) { entryInstance = getFromCache("below_brightness_" + lightLevel, () -> { @@ -111,7 +112,7 @@ public class SpawnRuleBulder { /** * Will spawn entity only above specified brightness value. * @param lightLevel light level lower limit. - * @return same {@link SpawnRuleBulder} instance + * @return same {@link SpawnRuleBulder} instance. */ public SpawnRuleBulder aboveBrightness(int lightLevel) { entryInstance = getFromCache("above_brightness_" + lightLevel, () -> { @@ -124,7 +125,7 @@ public class SpawnRuleBulder { /** * 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 SpawnRuleBulder} instance + * @return same {@link SpawnRuleBulder} instance. */ public SpawnRuleBulder hostile(int lightLevel) { return notPeaceful().belowBrightness(lightLevel); @@ -132,7 +133,7 @@ public class SpawnRuleBulder { /** * Entity spawn will follow common vanilla spawn rules - spawn in darkness (below light level 7) and not on peaceful level. - * @return same {@link SpawnRuleBulder} instance + * @return same {@link SpawnRuleBulder} instance. */ public SpawnRuleBulder vanillaHostile() { return hostile(7); @@ -143,7 +144,7 @@ public class SpawnRuleBulder { * @param selectorType selector {@link EntityType} to search. * @param count max entity count. * @param side side of box to search in. - * @return same {@link SpawnRuleBulder} instance + * @return same {@link SpawnRuleBulder} instance. */ public SpawnRuleBulder maxNearby(EntityType selectorType, int count, int side) { final Class baseClass = selectorType.getBaseClass(); @@ -167,7 +168,7 @@ public class SpawnRuleBulder { * 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 SpawnRuleBulder} instance + * @return same {@link SpawnRuleBulder} instance. */ public SpawnRuleBulder maxNearby(int count, int side) { return maxNearby(entityType, count, side); @@ -176,12 +177,22 @@ public class SpawnRuleBulder { /** * 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 SpawnRuleBulder} instance + * @return same {@link SpawnRuleBulder} instance. */ public SpawnRuleBulder maxNearby(int count) { return maxNearby(entityType, count, 256); } + /** + * Allows to add custom spawning rule for specific entities. + * @param rule {@SpawnRule} rule, can be a lambda expression. + * @return same {@link SpawnRuleBulder} instance. + */ + public SpawnRuleBulder customRule(SpawnRule rule) { + rules.add(new SpawnRuleEntry(7, rule)); + return this; + } + /** * Finalize spawning rule creation. * @param spawnType {@link Type} of spawn. From ffabd75e9523c9a926f586117724d6f3b16956e8 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 06:18:40 +0300 Subject: [PATCH 24/48] Javadoc fix --- src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java index 27819b2c..14e335b7 100644 --- a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java +++ b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java @@ -185,7 +185,7 @@ public class SpawnRuleBulder { /** * Allows to add custom spawning rule for specific entities. - * @param rule {@SpawnRule} rule, can be a lambda expression. + * @param rule {@link SpawnRule} rule, can be a lambda expression. * @return same {@link SpawnRuleBulder} instance. */ public SpawnRuleBulder customRule(SpawnRule rule) { From 3c606a914998d93be6a2ef798251821cb31e3b4a Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 06:39:20 +0300 Subject: [PATCH 25/48] Cleanup --- src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java index 14e335b7..1425ec0d 100644 --- a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java +++ b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java @@ -3,15 +3,12 @@ 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.MobSpawnType; import net.minecraft.world.entity.SpawnPlacements.SpawnPredicate; import net.minecraft.world.entity.SpawnPlacements.Type; -import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.levelgen.Heightmap.Types; import net.minecraft.world.phys.AABB; import ru.bclib.interfaces.SpawnRule; @@ -19,7 +16,6 @@ import ru.bclib.interfaces.SpawnRule; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Random; import java.util.function.Supplier; public class SpawnRuleBulder { From 99f958da37f7ca035f9f842bfd661af4f5241a3a Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 07:06:09 +0300 Subject: [PATCH 26/48] Block spawn restrictions --- .../bclib/api/spawning/SpawnRuleBulder.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java index 1425ec0d..1a328d29 100644 --- a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java +++ b/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java @@ -3,12 +3,14 @@ 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; @@ -79,6 +81,42 @@ public class SpawnRuleBulder { return this; } + /** + * Restricts spawning only to vanilla valid blocks. + * @return same {@link SpawnRuleBulder} instance. + */ + public SpawnRuleBulder onlyOnValidBlocks() { + entryInstance = getFromCache("below_max_height", () -> { + 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 SpawnRuleBulder} instance. + */ + public SpawnRuleBulder onlyOnBlocks(Block... blocks) { + final Block[] floorBlocks = blocks; + entryInstance = getFromCache("below_max_height", () -> { + 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. From 41141ec25137801b9cb46ffbf1fa4751c94a0007 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 07:09:04 +0300 Subject: [PATCH 27/48] Slab drop fix --- src/main/java/ru/bclib/blocks/BaseSlabBlock.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/bclib/blocks/BaseSlabBlock.java b/src/main/java/ru/bclib/blocks/BaseSlabBlock.java index 80550b77..ed9a6004 100644 --- a/src/main/java/ru/bclib/blocks/BaseSlabBlock.java +++ b/src/main/java/ru/bclib/blocks/BaseSlabBlock.java @@ -36,7 +36,8 @@ public class BaseSlabBlock extends SlabBlock implements BlockModelProvider { @Override @SuppressWarnings("deprecation") public List 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 From 32b7ca1608e8888c4daf32e32128030e991cbb4b Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 15:26:48 +0300 Subject: [PATCH 28/48] Entity spawn modification --- src/main/java/ru/bclib/api/BiomeAPI.java | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/main/java/ru/bclib/api/BiomeAPI.java b/src/main/java/ru/bclib/api/BiomeAPI.java index f8c1d1f4..f4464e74 100644 --- a/src/main/java/ru/bclib/api/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/BiomeAPI.java @@ -8,6 +8,8 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.impl.biome.InternalBiomeData; import net.fabricmc.fabric.mixin.biome.modification.GenerationSettingsAccessor; +import net.fabricmc.fabric.mixin.biome.modification.SpawnDensityAccessor; +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 +17,17 @@ 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.SpawnData; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.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; @@ -478,6 +486,24 @@ 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 void addBiomeMobSpawn(Biome biome, EntityType entityType, int weight, int minGroupCount, int maxGroupCount) { + MobCategory category = entityType.getCategory(); + SpawnSettingsAccessor accessor = (SpawnSettingsAccessor) biome.getMobSettings(); + Map> spawners = accessor.fabric_getSpawners(); + List 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 List getMutableList(List input) { if (input instanceof ImmutableList) { return Lists.newArrayList(input); From 94055c54543ca7d977c64765095de0e9f2d8056b Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 28 Nov 2021 14:27:02 +0100 Subject: [PATCH 29/48] Corrected Spelling and some Cache IDs --- src/main/java/ru/bclib/api/SpawnAPI.java | 126 ------------------ ...nRuleBulder.java => SpawnRuleBuilder.java} | 74 +++++----- 2 files changed, 39 insertions(+), 161 deletions(-) delete mode 100644 src/main/java/ru/bclib/api/SpawnAPI.java rename src/main/java/ru/bclib/api/spawning/{SpawnRuleBulder.java => SpawnRuleBuilder.java} (80%) diff --git a/src/main/java/ru/bclib/api/SpawnAPI.java b/src/main/java/ru/bclib/api/SpawnAPI.java deleted file mode 100644 index 1493ca99..00000000 --- a/src/main/java/ru/bclib/api/SpawnAPI.java +++ /dev/null @@ -1,126 +0,0 @@ -package ru.bclib.api; - -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.MobSpawnType; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.AABB; -import ru.bclib.util.BlocksHelper; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -@Deprecated(forRemoval = true) -public class SpawnAPI { - @FunctionalInterface - public interface SpawnRule { - boolean test(EntityType type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random); - } - - public interface IsBlock{ - boolean is(BlockState state); - } - - private Class entityClass; - public SpawnAPI(Class entityClass){ - this.entityClass = entityClass; - } - - ArrayList> rules = new ArrayList<>(); - - public SpawnAPI notPeaceful() { - rules.add((type, world, spawnReason, pos, random) -> world.getDifficulty() != Difficulty.PEACEFUL); - return this; - } - - public SpawnAPI notPeacefulBelowBrightness() { - return notPeacefulBelowBrightness(7); - } - - public SpawnAPI notPeacefulBelowBrightness(int bright) { - rules.add((type, world, spawnReason, pos, random) -> world.getDifficulty() != Difficulty.PEACEFUL && world.getMaxLocalRawBrightness(pos) <= bright); - return this; - } - - public SpawnAPI belowBrightness() { - return belowBrightness(7); - } - - public SpawnAPI belowBrightness(int bright) { - rules.add((type, world, spawnReason, pos, random) -> world.getMaxLocalRawBrightness(pos) <= bright); - return this; - } - - public SpawnAPI belowMaxHeight() { - rules.add((type, world, spawnReason, pos, random) -> pos.getY() >= world.dimensionType().logicalHeight()); - return this; - } - - public SpawnAPI maxAlive(){ - return maxAlive(4, 256); - } - - public SpawnAPI maxAlive(int count){ - return maxAlive(count, 256); - } - - public SpawnAPI maxAlive(int count, int size){ - rules.add((type, world, spawnReason, pos, random) -> { - try { - final AABB box = new AABB(pos).inflate(size, 256, size); - final List list = world.getEntitiesOfClass(entityClass, box, (entity) -> true); - return list.size() < count; - } - catch (Exception e) { - return true; - } - }); - return this; - } - - public SpawnAPI maxHeight(int height) { - rules.add((type, world, spawnReason, pos, random) -> { - int h = BlocksHelper.downRay(world, pos, height+1); - return h<=height; - }); - return this; - } - - public SpawnAPI notAboveBlock(IsBlock blockTest, int height) { - rules.add((type, world, spawnReason, pos, random) -> { - int h = BlocksHelper.downRay(world, pos, height+1); - if (h>height) return false; - - for (int i = 1; i <= h; i++) - if (blockTest.is(world.getBlockState(pos.below(i)))) - return false; - - return true; - }); - return this; - } - - public SpawnAPI aboveBlock(IsBlock blockTest, int height) { - rules.add((type, world, spawnReason, pos, random) -> { - int h = BlocksHelper.downRay(world, pos, height+1); - if (h>height) return false; - - for (int i = 1; i <= h; i++) - if (blockTest.is(world.getBlockState(pos.below(i)))) - return true; - - return false; - }); - return this; - } - - public boolean canSpawn(EntityType type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random) { - return rules.stream() - .map(r -> r.test(type, world, spawnReason, pos, random)) - .reduce(true, (p, c) -> p && c); - } -} diff --git a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java b/src/main/java/ru/bclib/api/spawning/SpawnRuleBuilder.java similarity index 80% rename from src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java rename to src/main/java/ru/bclib/api/spawning/SpawnRuleBuilder.java index 1a328d29..ac9395d8 100644 --- a/src/main/java/ru/bclib/api/spawning/SpawnRuleBulder.java +++ b/src/main/java/ru/bclib/api/spawning/SpawnRuleBuilder.java @@ -20,20 +20,20 @@ import java.util.List; import java.util.Map; import java.util.function.Supplier; -public class SpawnRuleBulder { +public class SpawnRuleBuilder { private static final Map RULES_CACHE = Maps.newHashMap(); - private static final SpawnRuleBulder INSTANCE = new SpawnRuleBulder(); + private static final SpawnRuleBuilder INSTANCE = new SpawnRuleBuilder(); private List rules = Lists.newArrayList(); private SpawnRuleEntry entryInstance; private EntityType entityType; - private SpawnRuleBulder() {} + private SpawnRuleBuilder() {} /** * Starts new rule building process. - * @return prepared {@link SpawnRuleBulder} instance. + * @return prepared {@link SpawnRuleBuilder} instance. */ - public static SpawnRuleBulder start(EntityType entityType) { + public static SpawnRuleBuilder start(EntityType entityType) { INSTANCE.entityType = entityType; INSTANCE.rules.clear(); return INSTANCE; @@ -41,9 +41,9 @@ public class SpawnRuleBulder { /** * Stop entity spawn on peaceful {@link Difficulty} - * @return same {@link SpawnRuleBulder} instance. + * @return same {@link SpawnRuleBuilder} instance. */ - public SpawnRuleBulder notPeaceful() { + public SpawnRuleBuilder notPeaceful() { entryInstance = getFromCache("not_peaceful", () -> { return new SpawnRuleEntry(0, (type, world, spawnReason, pos, random) -> world.getDifficulty() != Difficulty.PEACEFUL); }); @@ -54,9 +54,9 @@ public class SpawnRuleBulder { /** * Restricts entity spawn above world surface (flying mobs). * @param minHeight minimal spawn height. - * @return same {@link SpawnRuleBulder} instance. + * @return same {@link SpawnRuleBuilder} instance. */ - public SpawnRuleBulder aboveGround(int minHeight) { + public SpawnRuleBuilder aboveGround(int minHeight) { entryInstance = getFromCache("above_ground", () -> { return new SpawnRuleEntry(0, (type, world, spawnReason, pos, random) -> { if (pos.getY() < world.getMinBuildHeight() + 2) { @@ -71,9 +71,9 @@ public class SpawnRuleBulder { /** * Restricts entity spawn below world logical height (useful for Nether mobs). - * @return same {@link SpawnRuleBulder} instance. + * @return same {@link SpawnRuleBuilder} instance. */ - public SpawnRuleBulder belowMaxHeight() { + public SpawnRuleBuilder belowMaxHeight() { entryInstance = getFromCache("below_max_height", () -> { return new SpawnRuleEntry(0, (type, world, spawnReason, pos, random) -> pos.getY() < world.dimensionType().logicalHeight()); }); @@ -83,9 +83,9 @@ public class SpawnRuleBulder { /** * Restricts spawning only to vanilla valid blocks. - * @return same {@link SpawnRuleBulder} instance. + * @return same {@link SpawnRuleBuilder} instance. */ - public SpawnRuleBulder onlyOnValidBlocks() { + public SpawnRuleBuilder onlyOnValidBlocks() { entryInstance = getFromCache("below_max_height", () -> { return new SpawnRuleEntry(0, (type, world, spawnReason, pos, random) -> { BlockPos below = pos.below(); @@ -98,11 +98,15 @@ public class SpawnRuleBulder { /** * Restricts spawning only to specified blocks. - * @return same {@link SpawnRuleBulder} instance. + * @return same {@link SpawnRuleBuilder} instance. */ - public SpawnRuleBulder onlyOnBlocks(Block... blocks) { + public SpawnRuleBuilder onlyOnBlocks(Block... blocks) { + String id = "" + blocks.length; + for(Block bl : blocks){ + id += "_" + bl.getDescriptionId(); + } final Block[] floorBlocks = blocks; - entryInstance = getFromCache("below_max_height", () -> { + entryInstance = getFromCache("below_max_height_" + id, () -> { return new SpawnRuleEntry(0, (type, world, spawnReason, pos, random) -> { Block below = world.getBlockState(pos.below()).getBlock(); for (Block floor: floorBlocks) { @@ -120,9 +124,9 @@ public class SpawnRuleBulder { /** * Will spawn entity with 1 / chance probability (randomly). * @param chance probability limit. - * @return same {@link SpawnRuleBulder} instance. + * @return same {@link SpawnRuleBuilder} instance. */ - public SpawnRuleBulder withChance(int chance) { + public SpawnRuleBuilder withChance(int chance) { entryInstance = getFromCache("with_chance_" + chance, () -> { return new SpawnRuleEntry(1, (type, world, spawnReason, pos, random) -> random.nextInt(chance) == 0); }); @@ -133,9 +137,9 @@ public class SpawnRuleBulder { /** * Will spawn entity only below specified brightness value. * @param lightLevel light level upper limit. - * @return same {@link SpawnRuleBulder} instance. + * @return same {@link SpawnRuleBuilder} instance. */ - public SpawnRuleBulder belowBrightness(int lightLevel) { + public SpawnRuleBuilder belowBrightness(int lightLevel) { entryInstance = getFromCache("below_brightness_" + lightLevel, () -> { return new SpawnRuleEntry(2, (type, world, spawnReason, pos, random) -> world.getMaxLocalRawBrightness(pos) <= lightLevel); }); @@ -146,9 +150,9 @@ public class SpawnRuleBulder { /** * Will spawn entity only above specified brightness value. * @param lightLevel light level lower limit. - * @return same {@link SpawnRuleBulder} instance. + * @return same {@link SpawnRuleBuilder} instance. */ - public SpawnRuleBulder aboveBrightness(int lightLevel) { + public SpawnRuleBuilder aboveBrightness(int lightLevel) { entryInstance = getFromCache("above_brightness_" + lightLevel, () -> { return new SpawnRuleEntry(2, (type, world, spawnReason, pos, random) -> world.getMaxLocalRawBrightness(pos) >= lightLevel); }); @@ -159,17 +163,17 @@ public class SpawnRuleBulder { /** * 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 SpawnRuleBulder} instance. + * @return same {@link SpawnRuleBuilder} instance. */ - public SpawnRuleBulder hostile(int lightLevel) { + 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 SpawnRuleBulder} instance. + * @return same {@link SpawnRuleBuilder} instance. */ - public SpawnRuleBulder vanillaHostile() { + public SpawnRuleBuilder vanillaHostile() { return hostile(7); } @@ -178,11 +182,11 @@ public class SpawnRuleBulder { * @param selectorType selector {@link EntityType} to search. * @param count max entity count. * @param side side of box to search in. - * @return same {@link SpawnRuleBulder} instance. + * @return same {@link SpawnRuleBuilder} instance. */ - public SpawnRuleBulder maxNearby(EntityType selectorType, int count, int side) { + public SpawnRuleBuilder maxNearby(EntityType selectorType, int count, int side) { final Class baseClass = selectorType.getBaseClass(); - entryInstance = getFromCache("max_nearby_" + selectorType.getDescriptionId(), () -> { + 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); @@ -202,27 +206,27 @@ public class SpawnRuleBulder { * 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 SpawnRuleBulder} instance. + * @return same {@link SpawnRuleBuilder} instance. */ - public SpawnRuleBulder maxNearby(int count, int side) { + 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 SpawnRuleBulder} instance. + * @return same {@link SpawnRuleBuilder} instance. */ - public SpawnRuleBulder maxNearby(int count) { + 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 SpawnRuleBulder} instance. + * @return same {@link SpawnRuleBuilder} instance. */ - public SpawnRuleBulder customRule(SpawnRule rule) { + public SpawnRuleBuilder customRule(SpawnRule rule) { rules.add(new SpawnRuleEntry(7, rule)); return this; } From 80df11526b7968d0a96744a5b325ec9135c2ab5d Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 17:10:59 +0300 Subject: [PATCH 30/48] Immutable fix --- src/main/java/ru/bclib/api/BiomeAPI.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/bclib/api/BiomeAPI.java b/src/main/java/ru/bclib/api/BiomeAPI.java index f4464e74..1e0de06a 100644 --- a/src/main/java/ru/bclib/api/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/BiomeAPI.java @@ -1,6 +1,7 @@ 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; @@ -497,7 +498,7 @@ public class BiomeAPI { public static void addBiomeMobSpawn(Biome biome, EntityType entityType, int weight, int minGroupCount, int maxGroupCount) { MobCategory category = entityType.getCategory(); SpawnSettingsAccessor accessor = (SpawnSettingsAccessor) biome.getMobSettings(); - Map> spawners = accessor.fabric_getSpawners(); + Map> spawners = getMutableMap(accessor.fabric_getSpawners()); List 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)); @@ -510,4 +511,11 @@ public class BiomeAPI { } return input; } + + private static Map getMutableMap(Map input) { + if (input instanceof ImmutableMap) { + return Maps.newHashMap(input); + } + return input; + } } From dde1276785c730476759127dd7395eac97ec10a9 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 19:29:41 +0300 Subject: [PATCH 31/48] Small fix --- src/main/java/ru/bclib/api/BiomeAPI.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/ru/bclib/api/BiomeAPI.java b/src/main/java/ru/bclib/api/BiomeAPI.java index 1e0de06a..8ba88385 100644 --- a/src/main/java/ru/bclib/api/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/BiomeAPI.java @@ -9,7 +9,6 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.impl.biome.InternalBiomeData; import net.fabricmc.fabric.mixin.biome.modification.GenerationSettingsAccessor; -import net.fabricmc.fabric.mixin.biome.modification.SpawnDensityAccessor; import net.fabricmc.fabric.mixin.biome.modification.SpawnSettingsAccessor; import net.minecraft.client.Minecraft; import net.minecraft.core.Registry; @@ -23,7 +22,6 @@ 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.SpawnData; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome.ClimateParameters; import net.minecraft.world.level.biome.BiomeSource; @@ -402,7 +400,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; } From cdbeede9f4183def1c99d00b35590ad348485cb9 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 28 Nov 2021 19:34:42 +0300 Subject: [PATCH 32/48] Small rule fixes --- .../ru/bclib/api/spawning/SpawnRuleBuilder.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/ru/bclib/api/spawning/SpawnRuleBuilder.java b/src/main/java/ru/bclib/api/spawning/SpawnRuleBuilder.java index ac9395d8..f1e54d8b 100644 --- a/src/main/java/ru/bclib/api/spawning/SpawnRuleBuilder.java +++ b/src/main/java/ru/bclib/api/spawning/SpawnRuleBuilder.java @@ -15,7 +15,9 @@ 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; @@ -86,7 +88,7 @@ public class SpawnRuleBuilder { * @return same {@link SpawnRuleBuilder} instance. */ public SpawnRuleBuilder onlyOnValidBlocks() { - entryInstance = getFromCache("below_max_height", () -> { + 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); @@ -101,12 +103,14 @@ public class SpawnRuleBuilder { * @return same {@link SpawnRuleBuilder} instance. */ public SpawnRuleBuilder onlyOnBlocks(Block... blocks) { - String id = "" + blocks.length; - for(Block bl : blocks){ - id += "_" + bl.getDescriptionId(); - } + StringBuilder builder = new StringBuilder(); final Block[] floorBlocks = blocks; - entryInstance = getFromCache("below_max_height_" + id, () -> { + Arrays.sort(floorBlocks, Comparator.comparing(Block::getDescriptionId)); + for (Block block : floorBlocks) { + builder.append('_'); + builder.append(block.getDescriptionId()); + } + entryInstance = getFromCache("only_on_blocks" + builder, () -> { return new SpawnRuleEntry(0, (type, world, spawnReason, pos, random) -> { Block below = world.getBlockState(pos.below()).getBlock(); for (Block floor: floorBlocks) { From 0e31f9b22e06cdc5476814a2aae074c868c18e2a Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 28 Nov 2021 21:58:38 +0100 Subject: [PATCH 33/48] Added `DespawnableAnimal` --- .../java/ru/bclib/entity/DespawnableAnimal.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/main/java/ru/bclib/entity/DespawnableAnimal.java diff --git a/src/main/java/ru/bclib/entity/DespawnableAnimal.java b/src/main/java/ru/bclib/entity/DespawnableAnimal.java new file mode 100644 index 00000000..197673a1 --- /dev/null +++ b/src/main/java/ru/bclib/entity/DespawnableAnimal.java @@ -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 entityType, Level level) { + super(entityType, level); + } + + @Override + public boolean removeWhenFarAway(double d) { + return !this.hasCustomName(); + } +} From f61845f0c4a1a3b26faafedab1779fd7f0f78783 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Mon, 29 Nov 2021 08:03:25 +0300 Subject: [PATCH 34/48] Small optimisation --- src/main/java/ru/bclib/api/spawning/SpawnRuleBuilder.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/bclib/api/spawning/SpawnRuleBuilder.java b/src/main/java/ru/bclib/api/spawning/SpawnRuleBuilder.java index f1e54d8b..02ca1ccd 100644 --- a/src/main/java/ru/bclib/api/spawning/SpawnRuleBuilder.java +++ b/src/main/java/ru/bclib/api/spawning/SpawnRuleBuilder.java @@ -103,14 +103,16 @@ public class SpawnRuleBuilder { * @return same {@link SpawnRuleBuilder} instance. */ public SpawnRuleBuilder onlyOnBlocks(Block... blocks) { - StringBuilder builder = new StringBuilder(); 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("only_on_blocks" + builder, () -> { + + entryInstance = getFromCache(builder.toString(), () -> { return new SpawnRuleEntry(0, (type, world, spawnReason, pos, random) -> { Block below = world.getBlockState(pos.below()).getBlock(); for (Block floor: floorBlocks) { @@ -121,6 +123,7 @@ public class SpawnRuleBuilder { return false; }); }); + rules.add(entryInstance); return this; } From a489655ddd914043a3ca32b412654d9171a6d5a3 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 29 Nov 2021 14:31:44 +0100 Subject: [PATCH 35/48] New API to hook into level loading --- src/main/java/ru/bclib/api/LifeCycleAPI.java | 121 ++++++++++++++++++ .../bclib/mixin/common/ServerLevelMixin.java | 4 + 2 files changed, 125 insertions(+) create mode 100644 src/main/java/ru/bclib/api/LifeCycleAPI.java diff --git a/src/main/java/ru/bclib/api/LifeCycleAPI.java b/src/main/java/ru/bclib/api/LifeCycleAPI.java new file mode 100644 index 00000000..802853dc --- /dev/null +++ b/src/main/java/ru/bclib/api/LifeCycleAPI.java @@ -0,0 +1,121 @@ +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.LevelStorageSource.LevelStorageAccess; +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 onLoadLevelBiomes = new ArrayList<>(2); + private final static List 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 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 resourceKey, + DimensionType dimensionType, + ChunkProgressListener chunkProgressListener, + ChunkGenerator chunkGenerator, + boolean bl, + long l, + List 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 _onLevelLoad(ServerLevel world, + MinecraftServer minecraftServer, + Executor executor, + LevelStorageSource.LevelStorageAccess levelStorageAccess, + ServerLevelData serverLevelData, + ResourceKey resourceKey, + DimensionType dimensionType, + ChunkProgressListener chunkProgressListener, + ChunkGenerator chunkGenerator, + boolean bl, + long l, + List 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 biomeRegistry = world.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY); + onLoadLevelBiomes.forEach(c -> c.onLoad(world, seed, biomeRegistry)); + } +} diff --git a/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java b/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java index 8de68864..232e3c0f 100644 --- a/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java +++ b/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java @@ -17,6 +17,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 ru.bclib.api.LifeCycleAPI; import java.util.List; import java.util.concurrent.Executor; @@ -40,5 +41,8 @@ public abstract class ServerLevelMixin extends Level { } bclib_lastWorld = session.getLevelId(); + + ServerLevel world = ServerLevel.class.cast(this); + LifeCycleAPI._onLevelLoad(world, server, workerExecutor, session, properties, registryKey, dimensionType, worldGenerationProgressListener, chunkGenerator, debugWorld, l, list, bl); } } From 10037292085488ab2d5465e7d40f4165b847ed95 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 29 Nov 2021 14:40:37 +0100 Subject: [PATCH 36/48] `makeOreFeature` does not assuem END_STONE as HostBlock --- src/main/java/ru/bclib/world/features/BCLFeature.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/ru/bclib/world/features/BCLFeature.java b/src/main/java/ru/bclib/world/features/BCLFeature.java index b7b898d0..4fe1b764 100644 --- a/src/main/java/ru/bclib/world/features/BCLFeature.java +++ b/src/main/java/ru/bclib/world/features/BCLFeature.java @@ -4,7 +4,6 @@ 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.VerticalAnchor; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; @@ -61,9 +60,9 @@ public class BCLFeature { 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) { + public static BCLFeature makeOreFeature(ResourceLocation id, Block blockOre, Block hostBlock, int veins, int veinSize, int offset, int minY, int maxY) { OreConfiguration featureConfig = new OreConfiguration( - new BlockMatchTest(Blocks.END_STONE), + new BlockMatchTest(hostBlock), blockOre.defaultBlockState(), veinSize ); From 7f95d19bce146f42c7515a934d577fdcdad0ea2c Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 29 Nov 2021 14:45:34 +0100 Subject: [PATCH 37/48] Removed unneeded line --- src/main/java/ru/bclib/world/features/BCLFeature.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ru/bclib/world/features/BCLFeature.java b/src/main/java/ru/bclib/world/features/BCLFeature.java index 4fe1b764..fc16e06c 100644 --- a/src/main/java/ru/bclib/world/features/BCLFeature.java +++ b/src/main/java/ru/bclib/world/features/BCLFeature.java @@ -66,7 +66,7 @@ public class BCLFeature { blockOre.defaultBlockState(), veinSize ); - OreConfiguration config = new OreConfiguration(ANY_TERRAIN, blockOre.defaultBlockState(), 33); + //OreConfiguration config = new OreConfiguration(ANY_TERRAIN, blockOre.defaultBlockState(), 33); ConfiguredFeature oreFeature = Feature.ORE .configured(featureConfig) .rangeUniform( From 2708eb989a540eb6ab4ca7cfc0a0e8a49c51b003 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Mon, 29 Nov 2021 18:27:57 +0300 Subject: [PATCH 38/48] Chunk feature changes --- .../java/ru/bclib/world/features/BCLFeature.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/bclib/world/features/BCLFeature.java b/src/main/java/ru/bclib/world/features/BCLFeature.java index fc16e06c..b3fa29a9 100644 --- a/src/main/java/ru/bclib/world/features/BCLFeature.java +++ b/src/main/java/ru/bclib/world/features/BCLFeature.java @@ -82,11 +82,23 @@ public class BCLFeature { ); } - public static BCLFeature makeChunkFeature(ResourceLocation id, Feature feature) { + /** + * Will create feature which will be generated once in each chunk. + * @param id {@link ResourceLocation} feature ID. + * @param step {@link GenerationStep.Decoration} feature step. + * @param feature {@link Feature} with {@link NoneFeatureConfiguration} config. + * @return new BCLFeature instance. + */ + public static BCLFeature makeChunkFeature(ResourceLocation id, GenerationStep.Decoration step, Feature 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); + } + + @Deprecated(forRemoval = true) + public static BCLFeature makeChunkFeature(ResourceLocation id, Feature feature) { + return makeChunkFeature(id, GenerationStep.Decoration.LOCAL_MODIFICATIONS, feature); } public static BCLFeature makeChansedFeature(ResourceLocation id, Feature feature, int chance) { From c734f83c1349d1cee7f89001baf28b85ebc09efc Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Mon, 29 Nov 2021 18:48:04 +0300 Subject: [PATCH 39/48] BCLFeature enhancements and javadocs --- .../ru/bclib/world/features/BCLFeature.java | 151 ++++++++++++------ 1 file changed, 99 insertions(+), 52 deletions(-) diff --git a/src/main/java/ru/bclib/world/features/BCLFeature.java b/src/main/java/ru/bclib/world/features/BCLFeature.java index b3fa29a9..8d41c94e 100644 --- a/src/main/java/ru/bclib/world/features/BCLFeature.java +++ b/src/main/java/ru/bclib/world/features/BCLFeature.java @@ -4,7 +4,7 @@ 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.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; @@ -15,58 +15,80 @@ 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 Decoration featureStep; private Feature feature; - public BCLFeature(Feature feature, ConfiguredFeature configuredFeature, GenerationStep.Decoration featureStep) { + public BCLFeature(Feature feature, ConfiguredFeature configuredFeature, Decoration featureStep) { this.featureConfigured = configuredFeature; this.featureStep = featureStep; this.feature = feature; } - public BCLFeature(ResourceLocation id, Feature feature, GenerationStep.Decoration featureStep, ConfiguredFeature configuredFeature) { + public BCLFeature(ResourceLocation id, Feature 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; } + /** + * Get raw feature. + * @return {@link Feature}. + */ + public 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 Feature} with {@link NoneFeatureConfiguration} config. + * @param density iterations per chunk. + * @return new BCLFeature instance. + */ public static BCLFeature makeVegetationFeature(ResourceLocation id, Feature 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 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 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, Block hostBlock, 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(hostBlock), blockOre.defaultBlockState(), veinSize ); - //OreConfiguration config = new OreConfiguration(ANY_TERRAIN, blockOre.defaultBlockState(), 33); ConfiguredFeature oreFeature = Feature.ORE .configured(featureConfig) .rangeUniform( @@ -78,56 +100,81 @@ public class BCLFeature { return new BCLFeature( Feature.ORE, Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, id, oreFeature), - GenerationStep.Decoration.UNDERGROUND_ORES + Decoration.UNDERGROUND_ORES ); } /** * Will create feature which will be generated once in each chunk. * @param id {@link ResourceLocation} feature ID. - * @param step {@link GenerationStep.Decoration} feature step. + * @param step {@link Decoration} feature step. * @param feature {@link Feature} with {@link NoneFeatureConfiguration} config. * @return new BCLFeature instance. */ - public static BCLFeature makeChunkFeature(ResourceLocation id, GenerationStep.Decoration step, Feature feature) { + public static BCLFeature makeChunkFeature(ResourceLocation id, Decoration step, Feature feature) { ConfiguredFeature configured = feature .configured(FeatureConfiguration.NONE) .decorated(FeatureDecorator.COUNT.configured(new CountConfiguration(1))); return new BCLFeature(id, feature, step, configured); } - @Deprecated(forRemoval = true) - public static BCLFeature makeChunkFeature(ResourceLocation id, Feature feature) { - return makeChunkFeature(id, GenerationStep.Decoration.LOCAL_MODIFICATIONS, feature); - } - - public static BCLFeature makeChansedFeature(ResourceLocation id, Feature 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 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, Feature 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); } + /** + * Will create feature with specified generation iterations per chunk. + * @param id {@link ResourceLocation} feature ID. + * @param step {@link Decoration} feature step. + * @param feature {@link Feature} with {@link NoneFeatureConfiguration} config. + * @param count iterations steps. + * @return new BCLFeature instance. + */ + public static BCLFeature makeCountFeature(ResourceLocation id, Decoration step, Feature feature, int count) { + ConfiguredFeature configured = feature + .configured(FeatureConfiguration.NONE) + .decorated(FeatureDecorator.COUNT.configured(new CountConfiguration(count))); + return new BCLFeature(id, feature, step, configured); + } + + @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); + } + + @Deprecated(forRemoval = true) + public static BCLFeature makeRawGenFeature(ResourceLocation id, Feature feature, int chance) { + return makeChancedFeature(id, Decoration.RAW_GENERATION, feature, chance); + } + + @Deprecated(forRemoval = true) + public static BCLFeature makeChunkFeature(ResourceLocation id, Feature feature) { + return makeChunkFeature(id, Decoration.LOCAL_MODIFICATIONS, feature); + } + + @Deprecated(forRemoval = true) + public static BCLFeature makeChansedFeature(ResourceLocation id, Feature feature, int chance) { + return makeChancedFeature(id, Decoration.SURFACE_STRUCTURES, feature, chance); + } + + @Deprecated(forRemoval = true) public static BCLFeature makeCountRawFeature(ResourceLocation id, Feature 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); + return makeCountFeature(id, Decoration.RAW_GENERATION, feature, chance); } public static BCLFeature makeFeatureConfigured(ResourceLocation id, Feature feature) { ConfiguredFeature configured = feature.configured(FeatureConfiguration.NONE); - return new BCLFeature(id, feature, GenerationStep.Decoration.RAW_GENERATION, configured); - } - - public Feature getFeature() { - return feature; - } - - public ConfiguredFeature getFeatureConfigured() { - return featureConfigured; - } - - public GenerationStep.Decoration getFeatureStep() { - return featureStep; + return new BCLFeature(id, feature, Decoration.RAW_GENERATION, configured); } } From e4ca217170ff9eff03f8be075a34e658ba1eff37 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Mon, 29 Nov 2021 18:50:38 +0300 Subject: [PATCH 40/48] More enhancements --- .../java/ru/bclib/world/features/BCLFeature.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/bclib/world/features/BCLFeature.java b/src/main/java/ru/bclib/world/features/BCLFeature.java index 8d41c94e..02e43132 100644 --- a/src/main/java/ru/bclib/world/features/BCLFeature.java +++ b/src/main/java/ru/bclib/world/features/BCLFeature.java @@ -148,6 +148,18 @@ public class BCLFeature { return new BCLFeature(id, feature, step, configured); } + /** + * 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 Feature} with {@link NoneFeatureConfiguration} config. + * @return new BCLFeature instance. + */ + public static BCLFeature makeFeatureConfigured(ResourceLocation id, Decoration step, Feature feature) { + ConfiguredFeature configured = feature.configured(FeatureConfiguration.NONE); + return new BCLFeature(id, feature, step, configured); + } + @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); @@ -173,8 +185,8 @@ public class BCLFeature { return makeCountFeature(id, Decoration.RAW_GENERATION, feature, chance); } + @Deprecated(forRemoval = true) public static BCLFeature makeFeatureConfigured(ResourceLocation id, Feature feature) { - ConfiguredFeature configured = feature.configured(FeatureConfiguration.NONE); - return new BCLFeature(id, feature, Decoration.RAW_GENERATION, configured); + return makeFeatureConfigured(id, Decoration.RAW_GENERATION, feature); } } From bf8368b5153edbb20edfaa0078db101fba59e57b Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 29 Nov 2021 17:47:50 +0100 Subject: [PATCH 41/48] Revert "New API to hook into level loading" This reverts commit a489655ddd914043a3ca32b412654d9171a6d5a3. --- src/main/java/ru/bclib/api/LifeCycleAPI.java | 121 ------------------ .../bclib/mixin/common/ServerLevelMixin.java | 4 - 2 files changed, 125 deletions(-) delete mode 100644 src/main/java/ru/bclib/api/LifeCycleAPI.java diff --git a/src/main/java/ru/bclib/api/LifeCycleAPI.java b/src/main/java/ru/bclib/api/LifeCycleAPI.java deleted file mode 100644 index 802853dc..00000000 --- a/src/main/java/ru/bclib/api/LifeCycleAPI.java +++ /dev/null @@ -1,121 +0,0 @@ -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.LevelStorageSource.LevelStorageAccess; -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 onLoadLevelBiomes = new ArrayList<>(2); - private final static List 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 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 resourceKey, - DimensionType dimensionType, - ChunkProgressListener chunkProgressListener, - ChunkGenerator chunkGenerator, - boolean bl, - long l, - List 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 _onLevelLoad(ServerLevel world, - MinecraftServer minecraftServer, - Executor executor, - LevelStorageSource.LevelStorageAccess levelStorageAccess, - ServerLevelData serverLevelData, - ResourceKey resourceKey, - DimensionType dimensionType, - ChunkProgressListener chunkProgressListener, - ChunkGenerator chunkGenerator, - boolean bl, - long l, - List 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 biomeRegistry = world.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY); - onLoadLevelBiomes.forEach(c -> c.onLoad(world, seed, biomeRegistry)); - } -} diff --git a/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java b/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java index 232e3c0f..8de68864 100644 --- a/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java +++ b/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java @@ -17,7 +17,6 @@ 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 ru.bclib.api.LifeCycleAPI; import java.util.List; import java.util.concurrent.Executor; @@ -41,8 +40,5 @@ public abstract class ServerLevelMixin extends Level { } bclib_lastWorld = session.getLevelId(); - - ServerLevel world = ServerLevel.class.cast(this); - LifeCycleAPI._onLevelLoad(world, server, workerExecutor, session, properties, registryKey, dimensionType, worldGenerationProgressListener, chunkGenerator, debugWorld, l, list, bl); } } From bfea622998b88be0a60b979948347377210ff4c7 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 29 Nov 2021 17:49:38 +0100 Subject: [PATCH 42/48] Revert "Revert "New API to hook into level loading"" This reverts commit bf8368b5153edbb20edfaa0078db101fba59e57b. --- src/main/java/ru/bclib/api/LifeCycleAPI.java | 121 ++++++++++++++++++ .../bclib/mixin/common/ServerLevelMixin.java | 14 +- 2 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 src/main/java/ru/bclib/api/LifeCycleAPI.java diff --git a/src/main/java/ru/bclib/api/LifeCycleAPI.java b/src/main/java/ru/bclib/api/LifeCycleAPI.java new file mode 100644 index 00000000..802853dc --- /dev/null +++ b/src/main/java/ru/bclib/api/LifeCycleAPI.java @@ -0,0 +1,121 @@ +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.LevelStorageSource.LevelStorageAccess; +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 onLoadLevelBiomes = new ArrayList<>(2); + private final static List 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 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 resourceKey, + DimensionType dimensionType, + ChunkProgressListener chunkProgressListener, + ChunkGenerator chunkGenerator, + boolean bl, + long l, + List 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 _onLevelLoad(ServerLevel world, + MinecraftServer minecraftServer, + Executor executor, + LevelStorageSource.LevelStorageAccess levelStorageAccess, + ServerLevelData serverLevelData, + ResourceKey resourceKey, + DimensionType dimensionType, + ChunkProgressListener chunkProgressListener, + ChunkGenerator chunkGenerator, + boolean bl, + long l, + List 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 biomeRegistry = world.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY); + onLoadLevelBiomes.forEach(c -> c.onLoad(world, seed, biomeRegistry)); + } +} diff --git a/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java b/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java index 8de68864..61ecb78d 100644 --- a/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java +++ b/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java @@ -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 = "*", at = @At("TAIL")) private void bclib_onServerWorldInit(MinecraftServer server, Executor workerExecutor, LevelStorageSource.LevelStorageAccess session, ServerLevelData properties, ResourceKey registryKey, DimensionType dimensionType, ChunkProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long l, List list, boolean bl, CallbackInfo info) { + ServerLevel world = ServerLevel.class.cast(this); + LifeCycleAPI._onLevelLoad(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(); + + } } From 7d04b3c902b4a9005fc8028559a963e2b4b843d6 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 30 Nov 2021 16:27:22 +0100 Subject: [PATCH 43/48] Fix issue with immutable list detection --- src/main/java/ru/bclib/api/BiomeAPI.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/bclib/api/BiomeAPI.java b/src/main/java/ru/bclib/api/BiomeAPI.java index 8ba88385..5a69d8d4 100644 --- a/src/main/java/ru/bclib/api/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/BiomeAPI.java @@ -38,6 +38,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; @@ -507,7 +509,13 @@ public class BiomeAPI { } private static List getMutableList(List 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; From 0d325f76372efb665919e2d93f9b4611fe818904 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 30 Nov 2021 16:27:44 +0100 Subject: [PATCH 44/48] Version and dependency update --- gradle.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index e12f8ad5..d3887f7c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,11 +7,11 @@ loom_version=0.8-SNAPSHOT # Fabric Properties # check these on https://fabricmc.net/versions.html minecraft_version= 1.17.1 -loader_version= 0.12.4 -fabric_version = 0.41.3+1.17 +loader_version= 0.12.5 +fabric_version = 0.42.1+1.17 # Mod Properties -mod_version = 0.5.4 +mod_version = 0.5.5 maven_group = ru.bclib archives_base_name = bclib From c380f1d2dce9e82656199d27fa9cb9ab8cdcfb9e Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 30 Nov 2021 16:41:36 +0100 Subject: [PATCH 45/48] Removed unneeded test --- src/main/java/ru/bclib/api/BiomeAPI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ru/bclib/api/BiomeAPI.java b/src/main/java/ru/bclib/api/BiomeAPI.java index 5a69d8d4..e03a53d1 100644 --- a/src/main/java/ru/bclib/api/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/BiomeAPI.java @@ -515,7 +515,7 @@ public class BiomeAPI { System.out.println(" - " + cl.getName()); } } - if (input instanceof ImmutableList || !(input instanceof ArrayList || input instanceof LinkedList)) { + if (/*input instanceof ImmutableList ||*/ !(input instanceof ArrayList || input instanceof LinkedList)) { return Lists.newArrayList(input); } return input; From af8c3ba6e8f6d8c12898fe5a20d44e36065abbb1 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 30 Nov 2021 17:15:18 +0100 Subject: [PATCH 46/48] Name change --- src/main/java/ru/bclib/api/LifeCycleAPI.java | 26 +++++++++---------- .../bclib/mixin/common/ServerLevelMixin.java | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/java/ru/bclib/api/LifeCycleAPI.java b/src/main/java/ru/bclib/api/LifeCycleAPI.java index 802853dc..eddba849 100644 --- a/src/main/java/ru/bclib/api/LifeCycleAPI.java +++ b/src/main/java/ru/bclib/api/LifeCycleAPI.java @@ -85,19 +85,19 @@ public class LifeCycleAPI { * @param list * @param bl2 */ - public static void _onLevelLoad(ServerLevel world, - MinecraftServer minecraftServer, - Executor executor, - LevelStorageSource.LevelStorageAccess levelStorageAccess, - ServerLevelData serverLevelData, - ResourceKey resourceKey, - DimensionType dimensionType, - ChunkProgressListener chunkProgressListener, - ChunkGenerator chunkGenerator, - boolean bl, - long l, - List list, - boolean bl2){ + public static void _runLevelLoad(ServerLevel world, + MinecraftServer minecraftServer, + Executor executor, + LevelStorageSource.LevelStorageAccess levelStorageAccess, + ServerLevelData serverLevelData, + ResourceKey resourceKey, + DimensionType dimensionType, + ChunkProgressListener chunkProgressListener, + ChunkGenerator chunkGenerator, + boolean bl, + long l, + List list, + boolean bl2){ onLoadLevel.forEach(c -> c.onLoad( world, minecraftServer, diff --git a/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java b/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java index 61ecb78d..91c2c4d2 100644 --- a/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java +++ b/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java @@ -34,7 +34,7 @@ public abstract class ServerLevelMixin extends Level { @Inject(method = "*", at = @At("TAIL")) private void bclib_onServerWorldInit(MinecraftServer server, Executor workerExecutor, LevelStorageSource.LevelStorageAccess session, ServerLevelData properties, ResourceKey registryKey, DimensionType dimensionType, ChunkProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long l, List list, boolean bl, CallbackInfo info) { ServerLevel world = ServerLevel.class.cast(this); - LifeCycleAPI._onLevelLoad(world, server, workerExecutor, session, properties, registryKey, dimensionType, worldGenerationProgressListener, chunkGenerator, debugWorld, l, list, bl); + LifeCycleAPI._runLevelLoad(world, server, workerExecutor, session, properties, registryKey, dimensionType, worldGenerationProgressListener, chunkGenerator, debugWorld, l, list, bl); BiomeAPI.initRegistry(server); BiomeAPI.applyModifications(ServerLevel.class.cast(this)); From 4c576702ed6da2dd23991b22f8f60b19bc4bb2c6 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Tue, 30 Nov 2021 20:51:14 +0300 Subject: [PATCH 47/48] Version change --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index e12f8ad5..d5808982 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ loader_version= 0.12.4 fabric_version = 0.41.3+1.17 # Mod Properties -mod_version = 0.5.4 +mod_version = 0.5.5 maven_group = ru.bclib archives_base_name = bclib From 301701353fa9d09b9801d59a41964a8a38f0a72c Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Tue, 30 Nov 2021 20:55:05 +0300 Subject: [PATCH 48/48] Fixed recipe configs --- src/main/java/ru/bclib/recipes/AnvilRecipe.java | 13 ++++++------- src/main/java/ru/bclib/recipes/FurnaceRecipe.java | 2 +- src/main/java/ru/bclib/recipes/GridRecipe.java | 2 +- .../java/ru/bclib/recipes/SmithingTableRecipe.java | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/ru/bclib/recipes/AnvilRecipe.java b/src/main/java/ru/bclib/recipes/AnvilRecipe.java index 378a7fd9..4d8eab82 100644 --- a/src/main/java/ru/bclib/recipes/AnvilRecipe.java +++ b/src/main/java/ru/bclib/recipes/AnvilRecipe.java @@ -140,13 +140,12 @@ public class AnvilRecipe implements Recipe, UnknownReceipBookCategory @Override public NonNullList getIngredients() { NonNullList 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, UnknownReceipBookCategory } public Builder checkConfig(PathConfig config) { - exist |= config.getBoolean("anvil", id.getPath(), true); + exist &= config.getBoolean("anvil", id.getPath(), true); return this; } diff --git a/src/main/java/ru/bclib/recipes/FurnaceRecipe.java b/src/main/java/ru/bclib/recipes/FurnaceRecipe.java index fbdd57ea..a1986232 100644 --- a/src/main/java/ru/bclib/recipes/FurnaceRecipe.java +++ b/src/main/java/ru/bclib/recipes/FurnaceRecipe.java @@ -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; } diff --git a/src/main/java/ru/bclib/recipes/GridRecipe.java b/src/main/java/ru/bclib/recipes/GridRecipe.java index 71a6bbc9..95d68cfb 100644 --- a/src/main/java/ru/bclib/recipes/GridRecipe.java +++ b/src/main/java/ru/bclib/recipes/GridRecipe.java @@ -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; } diff --git a/src/main/java/ru/bclib/recipes/SmithingTableRecipe.java b/src/main/java/ru/bclib/recipes/SmithingTableRecipe.java index a74c6184..464ed15d 100644 --- a/src/main/java/ru/bclib/recipes/SmithingTableRecipe.java +++ b/src/main/java/ru/bclib/recipes/SmithingTableRecipe.java @@ -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; }