From 38eaf8be67f99fd6d8206dce76b979cf4464daaf Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 9 May 2021 19:14:19 +0300 Subject: [PATCH] Hydrogen compat fix (#154) --- src/main/java/ru/betterend/BetterEnd.java | 7 ++ .../common/ChunkBiomeContainerMixin.java | 73 +++++++++++++++++++ .../java/ru/betterend/registry/EndBiomes.java | 2 +- .../ru/betterend/registry/EndFeatures.java | 2 +- .../world/biome/air/BiomeIceStarfield.java | 1 + .../biome/land/PaintedMountainsBiome.java | 1 - 6 files changed, 83 insertions(+), 3 deletions(-) diff --git a/src/main/java/ru/betterend/BetterEnd.java b/src/main/java/ru/betterend/BetterEnd.java index 5ee920a1..577fa400 100644 --- a/src/main/java/ru/betterend/BetterEnd.java +++ b/src/main/java/ru/betterend/BetterEnd.java @@ -39,6 +39,8 @@ import ru.betterend.world.surface.SurfaceBuilders; public class BetterEnd implements ModInitializer { public static final String MOD_ID = "betterend"; public static final Logger LOGGER = Logger.get(); + private static boolean hasHydrogen; + @Override public void onInitialize() { EndPortals.loadPortals(); @@ -70,6 +72,7 @@ public class BetterEnd implements ModInitializer { if (hasGuideBook()) { GuideBookItem.register(); } + hasHydrogen = FabricLoader.getInstance().isModLoaded("hydrogen"); FabricLoader.getInstance().getEntrypoints("betterend", BetterEndPlugin.class).forEach(BetterEndPlugin::register); Configs.saveConfigs(); @@ -88,6 +91,10 @@ public class BetterEnd implements ModInitializer { return FabricLoader.getInstance().isModLoaded("patchouli"); } + public static boolean hasHydrogen() { + return hasHydrogen; + } + public static ResourceLocation makeID(String path) { return new ResourceLocation(MOD_ID, path); } diff --git a/src/main/java/ru/betterend/mixin/common/ChunkBiomeContainerMixin.java b/src/main/java/ru/betterend/mixin/common/ChunkBiomeContainerMixin.java index 9733e648..d67df70b 100644 --- a/src/main/java/ru/betterend/mixin/common/ChunkBiomeContainerMixin.java +++ b/src/main/java/ru/betterend/mixin/common/ChunkBiomeContainerMixin.java @@ -1,13 +1,17 @@ package ru.betterend.mixin.common; +import java.lang.reflect.Field; + import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import net.minecraft.core.BlockPos; +import net.minecraft.util.BitStorage; import net.minecraft.util.Mth; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.chunk.ChunkBiomeContainer; +import ru.betterend.BetterEnd; import ru.betterend.interfaces.IBiomeArray; @Mixin(ChunkBiomeContainer.class) @@ -34,6 +38,42 @@ public class ChunkBiomeContainerMixin implements IBiomeArray { int biomeY = pos.getY() >> 2; int biomeZ = pos.getZ() >> 2; int index = be_getArrayIndex(biomeX, biomeY, biomeZ); + + if (BetterEnd.hasHydrogen()) { + try { + ChunkBiomeContainer self = (ChunkBiomeContainer) (Object) this; + BitStorage storage = be_getHydrogenStorage(self); + Biome[] palette = be_getHydrogenPalette(self); + int paletteIndex = be_getHydrogenPaletteIndex(biome, palette); + if (paletteIndex == -1) { + Biome[] newPalette = new Biome[palette.length + 1]; + System.arraycopy(palette, 0, newPalette, 0, palette.length); + paletteIndex = palette.length; + palette = newPalette; + palette[paletteIndex] = biome; + be_setHydrogenPalette(self, palette); + } + try { + storage.set(index, paletteIndex); + } + catch (Exception e) { + int size = storage.getSize(); + int bits = Mth.ceillog2(palette.length); + BitStorage newStorage = new BitStorage(bits, size); + for (int i = 0; i < size; i++) { + newStorage.set(i, storage.get(i)); + } + storage = newStorage; + storage.set(index, paletteIndex); + be_setHydrogenStorage(self, storage); + } + } + catch (Exception e) { + BetterEnd.LOGGER.warning(e.getLocalizedMessage()); + } + return; + } + biomes[index] = biome; } @@ -43,4 +83,37 @@ public class ChunkBiomeContainerMixin implements IBiomeArray { int k = biomeZ & HORIZONTAL_MASK; return j << WIDTH_BITS + WIDTH_BITS | k << WIDTH_BITS | i; } + + private Field be_getField(String name) throws Exception { + Field field = ChunkBiomeContainer.class.getDeclaredField(name); + field.setAccessible(true); + return field; + } + + private BitStorage be_getHydrogenStorage(ChunkBiomeContainer container) throws Exception { + return (BitStorage) be_getField("intArray").get(container); + } + + private Biome[] be_getHydrogenPalette(ChunkBiomeContainer container) throws Exception { + return (Biome[]) be_getField("palette").get(container); + } + + private int be_getHydrogenPaletteIndex(Biome biome, Biome[] palette) { + int index = -1; + for (int i = 0; i < palette.length; i++) { + if (palette[i] == biome) { + index = i; + break; + } + } + return index; + } + + private void be_setHydrogenPalette(ChunkBiomeContainer container, Biome[] palette) throws Exception { + be_getField("palette").set(container, palette); + } + + private void be_setHydrogenStorage(ChunkBiomeContainer container, BitStorage storage) throws Exception { + be_getField("intArray").set(container, storage); + } } diff --git a/src/main/java/ru/betterend/registry/EndBiomes.java b/src/main/java/ru/betterend/registry/EndBiomes.java index db917709..5001dbc6 100644 --- a/src/main/java/ru/betterend/registry/EndBiomes.java +++ b/src/main/java/ru/betterend/registry/EndBiomes.java @@ -230,7 +230,7 @@ public class EndBiomes { * @param server - {@link MinecraftServer} */ public static void initRegistry(MinecraftServer server) { - if (biomeRegistry == null) { + if (biomeRegistry == null || biomeRegistry == BuiltinRegistries.BIOME) { biomeRegistry = server.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY); } } diff --git a/src/main/java/ru/betterend/registry/EndFeatures.java b/src/main/java/ru/betterend/registry/EndFeatures.java index 30337086..708fe2cb 100644 --- a/src/main/java/ru/betterend/registry/EndFeatures.java +++ b/src/main/java/ru/betterend/registry/EndFeatures.java @@ -257,7 +257,7 @@ public class EndFeatures { addFeature(ENDER_ORE, features); addFeature(CRASHED_SHIP, features); - if (EndBiomes.getBiome(id).hasCaves()) { + if (EndBiomes.getBiome(id).hasCaves() && !EndBiomes.VOID_BIOMES.containsImmutable(id)) { addFeature(ROUND_CAVE, features); addFeature(TUNEL_CAVE, features); } diff --git a/src/main/java/ru/betterend/world/biome/air/BiomeIceStarfield.java b/src/main/java/ru/betterend/world/biome/air/BiomeIceStarfield.java index f4d17ce0..55fc7b74 100644 --- a/src/main/java/ru/betterend/world/biome/air/BiomeIceStarfield.java +++ b/src/main/java/ru/betterend/world/biome/air/BiomeIceStarfield.java @@ -15,6 +15,7 @@ public class BiomeIceStarfield extends EndBiome { .setFogDensity(2.2F) .setFoliageColor(193, 244, 244) .setGenChance(0.25F) + .setCaves(false) .setParticles(EndParticles.SNOWFLAKE, 0.002F) .addStructureFeature(EndStructures.GIANT_ICE_STAR) .addFeature(EndFeatures.ICE_STAR) diff --git a/src/main/java/ru/betterend/world/biome/land/PaintedMountainsBiome.java b/src/main/java/ru/betterend/world/biome/land/PaintedMountainsBiome.java index 08e502a1..238520a5 100644 --- a/src/main/java/ru/betterend/world/biome/land/PaintedMountainsBiome.java +++ b/src/main/java/ru/betterend/world/biome/land/PaintedMountainsBiome.java @@ -13,7 +13,6 @@ public class PaintedMountainsBiome extends EndBiome { super(new BiomeDefinition("painted_mountains") .setFogColor(226, 239, 168) .setFogDensity(2) - .setCaves(false) .setWaterAndFogColor(192, 180, 131) .setMusic(EndSounds.MUSIC_OPENSPACE) .setLoop(EndSounds.AMBIENT_DUST_WASTELANDS)