diff --git a/build.gradle b/build.gradle index 8443606..3828e59 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,8 @@ //file:noinspection GroovyAssignabilityCheck buildscript { repositories { - maven { url = 'https://maven.minecraftforge.net' } - maven { url = 'https://maven.parchmentmc.org' } + maven { url 'https://maven.minecraftforge.net' } + maven { url 'https://maven.parchmentmc.org' } maven { url 'https://repo.spongepowered.org/repository/maven-public/' } mavenCentral() } diff --git a/src/main/java/com/xekr/ironstars/IronStars.java b/src/main/java/com/xekr/ironstars/IronStars.java index 0db61e7..6411ec4 100644 --- a/src/main/java/com/xekr/ironstars/IronStars.java +++ b/src/main/java/com/xekr/ironstars/IronStars.java @@ -1,10 +1,11 @@ package com.xekr.ironstars; +import com.xekr.ironstars.registry.AllBiomes; import com.xekr.ironstars.recipe.AnvilRecipeTypes; -import com.xekr.ironstars.recipe.RecipeEventHandler; import com.xekr.ironstars.registry.AllBlocks; import com.xekr.ironstars.registry.AllBlockEntities; import com.xekr.ironstars.registry.AllCapabilities; +import com.xekr.ironstars.registry.AllDimensions; import com.xekr.ironstars.registry.AllFluids; import com.xekr.ironstars.registry.AllItems; import net.minecraft.resources.ResourceLocation; @@ -20,7 +21,7 @@ public class IronStars { public static final String ID = "ironstars"; public static final String NAME = "Iron Stars"; - private static final Logger LOGGER = LogManager.getLogger(); + public static final Logger LOGGER = LogManager.getLogger(); public IronStars() { IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); @@ -29,11 +30,12 @@ public IronStars() { AllBlockEntities.register(bus); AllItems.register(bus); AllFluids.register(bus); + AllBiomes.register(bus); + AllDimensions.init(); AnvilRecipeTypes.init(); - MinecraftForge.EVENT_BUS.register(RecipeEventHandler.class); } - public static ResourceLocation asResource(String name) { + public static ResourceLocation id(String name) { return new ResourceLocation(ID, name); } } diff --git a/src/main/java/com/xekr/ironstars/IronStarsUtil.java b/src/main/java/com/xekr/ironstars/IronStarsUtil.java new file mode 100644 index 0000000..eb8eb43 --- /dev/null +++ b/src/main/java/com/xekr/ironstars/IronStarsUtil.java @@ -0,0 +1,8 @@ +package com.xekr.ironstars; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +public class IronStarsUtil { + public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); +} diff --git a/src/main/java/com/xekr/ironstars/mixin/AnvilBlockMixin.java b/src/main/java/com/xekr/ironstars/mixin/AnvilBlockMixin.java new file mode 100644 index 0000000..281b6cf --- /dev/null +++ b/src/main/java/com/xekr/ironstars/mixin/AnvilBlockMixin.java @@ -0,0 +1,20 @@ +package com.xekr.ironstars.mixin; + +import com.xekr.ironstars.recipe.AnvilFlatteningCraftingManager; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.item.FallingBlockEntity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.AnvilBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(AnvilBlock.class) +public class AnvilBlockMixin { + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;levelEvent(ILnet/minecraft/core/BlockPos;I)V"), method = "onLand") + private void onLand(Level level, BlockPos blockPos, BlockState state, BlockState targetState, FallingBlockEntity entity, CallbackInfo ci) { + AnvilFlatteningCraftingManager.craft(level, entity.blockPosition()); + } +} diff --git a/src/main/java/com/xekr/ironstars/recipe/RecipeEventHandler.java b/src/main/java/com/xekr/ironstars/recipe/RecipeEventHandler.java deleted file mode 100644 index 6687ae3..0000000 --- a/src/main/java/com/xekr/ironstars/recipe/RecipeEventHandler.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.xekr.ironstars.recipe; - -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.item.FallingBlockEntity; -import net.minecraft.world.level.block.AnvilBlock; -import net.minecraftforge.event.entity.EntityLeaveWorldEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; - -@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE) -public class RecipeEventHandler { -@SubscribeEvent -public static void onFallingAnvilRemoval(EntityLeaveWorldEvent event) {//FIXME -// System.out.printf("client=%s%n", event.getWorld().isClientSide()); - if (event.getWorld().isClientSide()) { - return; - } - Entity entity = event.getEntity(); -// System.out.printf("entity=%s, blockPos=%s%n", entity, entity.blockPosition()); - if (entity instanceof FallingBlockEntity fbEntity) { - if (fbEntity.getBlockState().getBlock() instanceof AnvilBlock) { - System.out.println(entity.blockPosition()); - AnvilFlatteningCraftingManager.craft(event.getWorld(), entity.blockPosition()); - } - } -} -} diff --git a/src/main/java/com/xekr/ironstars/registry/AllBiomes.java b/src/main/java/com/xekr/ironstars/registry/AllBiomes.java new file mode 100644 index 0000000..c573c89 --- /dev/null +++ b/src/main/java/com/xekr/ironstars/registry/AllBiomes.java @@ -0,0 +1,37 @@ +package com.xekr.ironstars.registry; + +import com.xekr.ironstars.IronStars; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeGenerationSettings; +import net.minecraft.world.level.biome.BiomeSpecialEffects; +import net.minecraft.world.level.biome.MobSpawnSettings; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; + +public class AllBiomes { + private static final DeferredRegister BIOMES = DeferredRegister.create(ForgeRegistries.BIOMES, IronStars.ID); + + public static final ResourceKey MOON = registerBiome("moon"); + + + private static ResourceKey registerBiome(String name) { + BIOMES.register(name, () -> new Biome.BiomeBuilder() + .precipitation(Biome.Precipitation.NONE) + .biomeCategory(Biome.BiomeCategory.NONE) + .downfall(0) + .temperature(0) + .specialEffects(new BiomeSpecialEffects.Builder().fogColor(0).waterColor(0).waterFogColor(0).skyColor(0).build()) + .generationSettings(new BiomeGenerationSettings.Builder().build()) + .mobSpawnSettings(new MobSpawnSettings.Builder().build()) + .temperatureAdjustment(Biome.TemperatureModifier.NONE) + .build()); + return ResourceKey.create(Registry.BIOME_REGISTRY, IronStars.id(name)); + } + + public static void register(IEventBus bus) { + BIOMES.register(bus); + } +} diff --git a/src/main/java/com/xekr/ironstars/registry/CreativeTab.java b/src/main/java/com/xekr/ironstars/registry/AllCreativeTab.java similarity index 97% rename from src/main/java/com/xekr/ironstars/registry/CreativeTab.java rename to src/main/java/com/xekr/ironstars/registry/AllCreativeTab.java index b6e8d60..5b8e342 100644 --- a/src/main/java/com/xekr/ironstars/registry/CreativeTab.java +++ b/src/main/java/com/xekr/ironstars/registry/AllCreativeTab.java @@ -5,7 +5,7 @@ import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.NotNull; -public class CreativeTab { +public class AllCreativeTab { public static final CreativeModeTab BASE = new CreativeModeTab(IronStars.ID + ".base") { @Override diff --git a/src/main/java/com/xekr/ironstars/registry/AllDimensions.java b/src/main/java/com/xekr/ironstars/registry/AllDimensions.java new file mode 100644 index 0000000..e1758e7 --- /dev/null +++ b/src/main/java/com/xekr/ironstars/registry/AllDimensions.java @@ -0,0 +1,16 @@ +package com.xekr.ironstars.registry; + +import com.xekr.ironstars.IronStars; +import com.xekr.ironstars.world.BiomeProvider; +import com.xekr.ironstars.world.ModChunkGenerator; +import net.minecraft.core.Registry; + +public class AllDimensions { + public static long seed; + public static void init() { + Registry.register(Registry.BIOME_SOURCE, IronStars.id("ironstars_biomes"), BiomeProvider.CODEC); + + Registry.register(Registry.CHUNK_GENERATOR, IronStars.id("structure_locating_wrapper"), ModChunkGenerator.CODEC); + } + +} diff --git a/src/main/java/com/xekr/ironstars/registry/AllEvents.java b/src/main/java/com/xekr/ironstars/registry/AllEvents.java index c2b3c93..5df4cfc 100644 --- a/src/main/java/com/xekr/ironstars/registry/AllEvents.java +++ b/src/main/java/com/xekr/ironstars/registry/AllEvents.java @@ -2,14 +2,18 @@ import com.mojang.brigadier.CommandDispatcher; import com.xekr.ironstars.command.TestCommand; +import com.xekr.ironstars.world.WorldGenerator; import net.minecraft.client.renderer.ItemBlockRenderTypes; import net.minecraft.client.renderer.RenderType; import net.minecraft.commands.CommandSourceStack; +import net.minecraft.data.DataGenerator; import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.common.data.ExistingFileHelper; import net.minecraftforge.event.RegisterCommandsEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.forge.event.lifecycle.GatherDataEvent; public final class AllEvents { @Mod.EventBusSubscriber @@ -22,13 +26,12 @@ public static void onCommandRegister(RegisterCommandsEvent event) { } @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) static class ModBusGlobal { // mod管线全局事件 -// @SubscribeEvent -// public static void gatherData(GatherDataEvent event) { -// DataGenerator generator = event.getGenerator(); -// ExistingFileHelper helper = event.getExistingFileHelper(); -// generator.addProvider(new WorldGenerator(generator)); -// -// } + @SubscribeEvent + public static void gatherData(GatherDataEvent event) { //TODO 不好使 + DataGenerator generator = event.getGenerator(); + ExistingFileHelper helper = event.getExistingFileHelper(); + generator.addProvider(new WorldGenerator(generator)); + } } @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) static class ModBusClient { // mod管线客户端事件 diff --git a/src/main/java/com/xekr/ironstars/registry/AllItemTags.java b/src/main/java/com/xekr/ironstars/registry/AllItemTags.java index 720cb6d..051b6f1 100644 --- a/src/main/java/com/xekr/ironstars/registry/AllItemTags.java +++ b/src/main/java/com/xekr/ironstars/registry/AllItemTags.java @@ -2,9 +2,9 @@ import net.minecraft.resources.ResourceLocation; -import static com.xekr.ironstars.IronStars.asResource; +import static com.xekr.ironstars.IronStars.id; public class AllItemTags { - public static final ResourceLocation TITANIUM = asResource("titanium_alloy"); + public static final ResourceLocation TITANIUM = id("titanium_alloy"); } diff --git a/src/main/java/com/xekr/ironstars/registry/AllItems.java b/src/main/java/com/xekr/ironstars/registry/AllItems.java index 647eac5..06d428b 100644 --- a/src/main/java/com/xekr/ironstars/registry/AllItems.java +++ b/src/main/java/com/xekr/ironstars/registry/AllItems.java @@ -10,7 +10,7 @@ import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.RegistryObject; -import static com.xekr.ironstars.registry.CreativeTab.*; +import static com.xekr.ironstars.registry.AllCreativeTab.*; @SuppressWarnings("unused") public class AllItems { diff --git a/src/main/java/com/xekr/ironstars/world/Area.java b/src/main/java/com/xekr/ironstars/world/Area.java new file mode 100644 index 0000000..b2ef0b9 --- /dev/null +++ b/src/main/java/com/xekr/ironstars/world/Area.java @@ -0,0 +1,5 @@ +package com.xekr.ironstars.world; + +public interface Area { + int get(int p_76486_, int p_76487_); +} diff --git a/src/main/java/com/xekr/ironstars/world/AreaFactory.java b/src/main/java/com/xekr/ironstars/world/AreaFactory.java new file mode 100644 index 0000000..7b610e0 --- /dev/null +++ b/src/main/java/com/xekr/ironstars/world/AreaFactory.java @@ -0,0 +1,5 @@ +package com.xekr.ironstars.world; + +public interface AreaFactory { + A make(); +} \ No newline at end of file diff --git a/src/main/java/com/xekr/ironstars/world/AreaTransformer0.java b/src/main/java/com/xekr/ironstars/world/AreaTransformer0.java new file mode 100644 index 0000000..2b0708a --- /dev/null +++ b/src/main/java/com/xekr/ironstars/world/AreaTransformer0.java @@ -0,0 +1,12 @@ +package com.xekr.ironstars.world; + +public interface AreaTransformer0 { + default AreaFactory run(BigContext p_76985_) { + return () -> p_76985_.createResult((p_164642_, p_164643_) -> { + p_76985_.initRandom(p_164642_, p_164643_); + return this.applyPixel(p_76985_, p_164642_, p_164643_); + }); + } + + int applyPixel(Context p_76990_, int p_76991_, int p_76992_); +} diff --git a/src/main/java/com/xekr/ironstars/world/BigContext.java b/src/main/java/com/xekr/ironstars/world/BigContext.java new file mode 100644 index 0000000..9607e71 --- /dev/null +++ b/src/main/java/com/xekr/ironstars/world/BigContext.java @@ -0,0 +1,30 @@ +package com.xekr.ironstars.world; + +public interface BigContext extends Context { + void initRandom(long p_76508_, long p_76509_); + + R createResult(PixelTransformer p_76510_); + + default R createResult(PixelTransformer p_76511_, R p_76512_) { + return this.createResult(p_76511_); + } + + default R createResult(PixelTransformer p_76513_, R p_76514_, R p_76515_) { + return this.createResult(p_76513_); + } + + default int random(int p_76501_, int p_76502_) { + return this.nextRandom(2) == 0 ? p_76501_ : p_76502_; + } + + default int random(int p_76504_, int p_76505_, int p_76506_, int p_76507_) { + int i = this.nextRandom(4); + if (i == 0) { + return p_76504_; + } else if (i == 1) { + return p_76505_; + } else { + return i == 2 ? p_76506_ : p_76507_; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/xekr/ironstars/world/BiomeProvider.java b/src/main/java/com/xekr/ironstars/world/BiomeProvider.java new file mode 100644 index 0000000..905e4b5 --- /dev/null +++ b/src/main/java/com/xekr/ironstars/world/BiomeProvider.java @@ -0,0 +1,96 @@ +package com.xekr.ironstars.world; + +import com.google.common.collect.ImmutableList; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import com.xekr.ironstars.registry.AllBiomes; +import com.xekr.ironstars.registry.AllDimensions; +import net.minecraft.core.Registry; +import net.minecraft.resources.RegistryLookupCodec; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeSource; +import net.minecraft.world.level.biome.Climate; + +import java.util.List; +import java.util.Optional; +import java.util.function.LongFunction; + +public class BiomeProvider extends BiomeSource { + public static final Codec CODEC = RecordCodecBuilder.create((instance) -> instance.group( + Codec.LONG.fieldOf("seed").stable().orElseGet(() -> AllDimensions.seed).forGetter((obj) -> obj.seed), + RegistryLookupCodec.create(Registry.BIOME_REGISTRY).forGetter(provider -> provider.registry) + ).apply(instance, instance.stable(BiomeProvider::new))); + + private static final List> BIOMES = ImmutableList.of(AllBiomes.MOON); + + private final Registry registry; + private final Layer genBiomes; + private final long seed; + + public BiomeProvider(long seed, Registry registryIn) { + super(BIOMES.stream().map(ResourceKey::location).map(registryIn::getOptional).filter(Optional::isPresent).map(opt -> opt::get)); + this.seed = seed; + registry = registryIn; + genBiomes = makeLayers(seed, registryIn); + + } + + public static int getBiomeId(ResourceKey biome, Registry registry) { + return registry.getId(registry.get(biome)); + } + + private static > AreaFactory makeLayers(LongFunction seed, Registry registry, long rawSeed) { + + AreaFactory biomes = GenLayerTFBiomes.INSTANCE.setup(registry).run(seed.apply(1L)); +// biomes = GenLayerTFKeyBiomes.INSTANCE.setup(registry, rawSeed).run(seed.apply(1000L), biomes); +// biomes = GenLayerTFCompanionBiomes.INSTANCE.setup(registry).run(seed.apply(1000L), biomes); +// +// biomes = ZoomLayer.NORMAL.run(seed.apply(1000L), biomes); +// biomes = ZoomLayer.NORMAL.run(seed.apply(1001L), biomes); +// +// biomes = GenLayerTFBiomeStabilize.INSTANCE.run(seed.apply(700L), biomes); +// +// biomes = GenLayerTFThornBorder.INSTANCE.setup(registry).run(seed.apply(500L), biomes); +// +// biomes = ZoomLayer.NORMAL.run(seed.apply(1002), biomes); +// biomes = ZoomLayer.NORMAL.run(seed.apply(1003), biomes); +// biomes = ZoomLayer.NORMAL.run(seed.apply(1004), biomes); +// biomes = ZoomLayer.NORMAL.run(seed.apply(1005), biomes); +// +// AreaFactory riverLayer = GenLayerTFStream.INSTANCE.setup(registry).run(seed.apply(1L), biomes); +// riverLayer = SmoothLayer.INSTANCE.run(seed.apply(7000L), riverLayer); +// biomes = GenLayerTFRiverMix.INSTANCE.setup(registry).run(seed.apply(100L), biomes, riverLayer); + + return biomes; + } + + public static Layer makeLayers(long seed, Registry registry) { + AreaFactory areaFactory = makeLayers((context) -> new LazyAreaContext(25, seed, context), registry, seed); + return new Layer(areaFactory) { + @Override + public Biome get(Registry p_242936_1_, int p_242936_2_, int p_242936_3_) { + int i = this.area.get(p_242936_2_, p_242936_3_); + Biome biome = registry.byId(i); + if (biome == null) + throw new IllegalStateException("Unknown biome id emitted by layers: " + i); + return biome; + } + }; + } + + @Override + protected Codec codec() { + return CODEC; + } + + @Override + public BiomeSource withSeed(long pSeed) { + return new BiomeProvider(pSeed, registry); + } + + @Override + public Biome getNoiseBiome(int p_186735_, int p_186736_, int p_186737_, Climate.Sampler p_186738_) { + return genBiomes.get(registry, p_186735_, p_186737_); + } +} diff --git a/src/main/java/com/xekr/ironstars/world/Context.java b/src/main/java/com/xekr/ironstars/world/Context.java new file mode 100644 index 0000000..290e8fc --- /dev/null +++ b/src/main/java/com/xekr/ironstars/world/Context.java @@ -0,0 +1,9 @@ +package com.xekr.ironstars.world; + +import net.minecraft.world.level.levelgen.synth.ImprovedNoise; + +public interface Context { + int nextRandom(int p_76516_); + + ImprovedNoise getBiomeNoise(); +} \ No newline at end of file diff --git a/src/main/java/com/xekr/ironstars/world/GenLayerTFBiomes.java b/src/main/java/com/xekr/ironstars/world/GenLayerTFBiomes.java new file mode 100644 index 0000000..fc285cd --- /dev/null +++ b/src/main/java/com/xekr/ironstars/world/GenLayerTFBiomes.java @@ -0,0 +1,50 @@ +package com.xekr.ironstars.world; + +import com.google.common.collect.ImmutableList; +import com.xekr.ironstars.registry.AllBiomes; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.biome.Biome; + +import java.util.List; + +/** + * Applies the twilight forest biomes to the map + * + * @author Ben + */ +public enum GenLayerTFBiomes implements AreaTransformer0 { + INSTANCE; + private static final int RARE_BIOME_CHANCE = 15; + + protected static final List> commonBiomes = ImmutableList.of(AllBiomes.MOON); + protected static final List> rareBiomes = ImmutableList.of(); + + private Registry registry; + + public GenLayerTFBiomes setup(Registry registry) { + this.registry = registry; + return this; + } + + GenLayerTFBiomes() { + + } + + @Override + public int applyPixel(Context iNoiseRandom, int x, int y) { + //return 0; //getRandomBiome(iNoiseRandom, commonBiomes)); + + if (iNoiseRandom.nextRandom(RARE_BIOME_CHANCE) == 0) { + // make specialBiomes biome + return getRandomBiome(iNoiseRandom, rareBiomes); + } else { + // make common biome + return getRandomBiome(iNoiseRandom, commonBiomes); + } + } + + private int getRandomBiome(Context random, List> biomes) { + return BiomeProvider.getBiomeId(biomes.get(random.nextRandom(biomes.size())), registry); + } +} diff --git a/src/main/java/com/xekr/ironstars/world/Layer.java b/src/main/java/com/xekr/ironstars/world/Layer.java new file mode 100644 index 0000000..d2a7938 --- /dev/null +++ b/src/main/java/com/xekr/ironstars/world/Layer.java @@ -0,0 +1,26 @@ +package com.xekr.ironstars.world; + +import net.minecraft.Util; +import net.minecraft.core.Registry; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Biomes; + +public class Layer { + public final LazyArea area; + + public Layer(AreaFactory p_76714_) { + this.area = p_76714_.make(); + } + + public Biome get(Registry p_76716_, int p_76717_, int p_76718_) { + int i = this.area.get(p_76717_, p_76718_); + Biome biome = p_76716_.byId(i); + if (biome == null) { + Util.logAndPauseIfInIde("Unknown biome id: " + i); + return p_76716_.get(Biomes.PLAINS); + } else { + return biome; + } + + } +} diff --git a/src/main/java/com/xekr/ironstars/world/LazyArea.java b/src/main/java/com/xekr/ironstars/world/LazyArea.java new file mode 100644 index 0000000..c401f36 --- /dev/null +++ b/src/main/java/com/xekr/ironstars/world/LazyArea.java @@ -0,0 +1,40 @@ +package com.xekr.ironstars.world; + +import it.unimi.dsi.fastutil.longs.Long2IntLinkedOpenHashMap; +import net.minecraft.world.level.ChunkPos; + +public class LazyArea implements Area { + private final PixelTransformer transformer; + private final Long2IntLinkedOpenHashMap cache; + private final int maxCache; + + public LazyArea(Long2IntLinkedOpenHashMap p_76493_, int p_76494_, PixelTransformer p_76495_) { + this.cache = p_76493_; + this.maxCache = p_76494_; + this.transformer = p_76495_; + } + + public int get(int p_76498_, int p_76499_) { + long i = ChunkPos.asLong(p_76498_, p_76499_); + synchronized(this.cache) { + int j = this.cache.get(i); + if (j != Integer.MIN_VALUE) { + return j; + } else { + int k = this.transformer.apply(p_76498_, p_76499_); + this.cache.put(i, k); + if (this.cache.size() > this.maxCache) { + for(int l = 0; l < this.maxCache / 16; ++l) { + this.cache.removeFirstInt(); + } + } + + return k; + } + } + } + + public int getMaxCache() { + return this.maxCache; + } +} diff --git a/src/main/java/com/xekr/ironstars/world/LazyAreaContext.java b/src/main/java/com/xekr/ironstars/world/LazyAreaContext.java new file mode 100644 index 0000000..cb9d60c --- /dev/null +++ b/src/main/java/com/xekr/ironstars/world/LazyAreaContext.java @@ -0,0 +1,62 @@ +package com.xekr.ironstars.world; + +import it.unimi.dsi.fastutil.longs.Long2IntLinkedOpenHashMap; +import net.minecraft.util.LinearCongruentialGenerator; +import net.minecraft.world.level.levelgen.LegacyRandomSource; +import net.minecraft.world.level.levelgen.synth.ImprovedNoise; + +public class LazyAreaContext implements BigContext { + private final Long2IntLinkedOpenHashMap cache; + private final int maxCache; + private final ImprovedNoise biomeNoise; + private final long seed; + private long rval; + + public LazyAreaContext(int p_76523_, long p_76524_, long p_76525_) { + this.seed = mixSeed(p_76524_, p_76525_); + this.biomeNoise = new ImprovedNoise(new LegacyRandomSource(p_76524_)); + this.cache = new Long2IntLinkedOpenHashMap(16, 0.25F); + this.cache.defaultReturnValue(Integer.MIN_VALUE); + this.maxCache = p_76523_; + } + + public LazyArea createResult(PixelTransformer p_76552_) { + return new LazyArea(this.cache, this.maxCache, p_76552_); + } + + public LazyArea createResult(PixelTransformer p_76541_, LazyArea p_76542_) { + return new LazyArea(this.cache, Math.min(1024, p_76542_.getMaxCache() * 4), p_76541_); + } + + public LazyArea createResult(PixelTransformer p_76544_, LazyArea p_76545_, LazyArea p_76546_) { + return new LazyArea(this.cache, Math.min(1024, Math.max(p_76545_.getMaxCache(), p_76546_.getMaxCache()) * 4), p_76544_); + } + + public void initRandom(long p_76529_, long p_76530_) { + long i = this.seed; + i = LinearCongruentialGenerator.next(i, p_76529_); + i = LinearCongruentialGenerator.next(i, p_76530_); + i = LinearCongruentialGenerator.next(i, p_76529_); + i = LinearCongruentialGenerator.next(i, p_76530_); + this.rval = i; + } + + public int nextRandom(int p_76527_) { + int i = Math.floorMod(this.rval >> 24, p_76527_); + this.rval = LinearCongruentialGenerator.next(this.rval, this.seed); + return i; + } + + public ImprovedNoise getBiomeNoise() { + return this.biomeNoise; + } + + private static long mixSeed(long p_76549_, long p_76550_) { + long i = LinearCongruentialGenerator.next(p_76550_, p_76550_); + i = LinearCongruentialGenerator.next(i, p_76550_); + i = LinearCongruentialGenerator.next(i, p_76550_); + long j = LinearCongruentialGenerator.next(p_76549_, i); + j = LinearCongruentialGenerator.next(j, i); + return LinearCongruentialGenerator.next(j, i); + } +} diff --git a/src/main/java/com/xekr/ironstars/world/ModChunkGenerator.java b/src/main/java/com/xekr/ironstars/world/ModChunkGenerator.java new file mode 100644 index 0000000..f52a635 --- /dev/null +++ b/src/main/java/com/xekr/ironstars/world/ModChunkGenerator.java @@ -0,0 +1,173 @@ +package com.xekr.ironstars.world; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import com.xekr.ironstars.registry.AllDimensions; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.WorldGenRegion; +import net.minecraft.util.random.WeightedRandomList; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.NoiseColumn; +import net.minecraft.world.level.StructureFeatureManager; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeManager; +import net.minecraft.world.level.biome.BiomeSource; +import net.minecraft.world.level.biome.Climate; +import net.minecraft.world.level.biome.MobSpawnSettings; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; +import net.minecraft.world.level.levelgen.StructureSettings; +import net.minecraft.world.level.levelgen.blending.Blender; +import net.minecraft.world.level.levelgen.feature.StructureFeature; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; +import org.jetbrains.annotations.Nullable; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +public class ModChunkGenerator extends ChunkGenerator { + public static final Codec CODEC = RecordCodecBuilder.create((instance) -> instance.group( + ChunkGenerator.CODEC.fieldOf("wrapped_generator").forGetter(o -> o.delegate), + Codec.BOOL.fieldOf("use_overworld_seed").forGetter(o -> false) // Don't make this persistent, we want to load the stored seed on existing worlds! This is purely used on world creation ONLY!! + ).apply(instance, instance.stable(ModChunkGenerator::new))); + public final ChunkGenerator delegate; + + public ModChunkGenerator(ChunkGenerator delegate, boolean owSeed) { + this(owSeed ? delegate.withSeed(AllDimensions.seed) : delegate); + } + + private ModChunkGenerator(ChunkGenerator delegate) { + super(delegate.getBiomeSource(), delegate.getBiomeSource(), delegate.getSettings(), delegate instanceof NoiseBasedChunkGenerator noiseGen ? noiseGen.seed : delegate.strongholdSeed); + this.delegate = delegate; + } + + @Override + public void createStructures(RegistryAccess pRegistryAccess, StructureFeatureManager pStructureFeatureManager, ChunkAccess pChunk, StructureManager pStructureManager, long pSeed) { + this.delegate.createStructures(pRegistryAccess, pStructureFeatureManager, pChunk, pStructureManager, pSeed); + } + + @Override + public void createReferences(WorldGenLevel pLevel, StructureFeatureManager pStructureFeatureManager, ChunkAccess pChunk) { + this.delegate.createReferences(pLevel, pStructureFeatureManager, pChunk); + } + + @Override + public int getFirstFreeHeight(int pX, int pZ, Heightmap.Types pType, LevelHeightAccessor pLevel) { + return this.delegate.getFirstFreeHeight(pX, pZ, pType, pLevel); + } + + @Override + public int getFirstOccupiedHeight(int pX, int pZ, Heightmap.Types pType, LevelHeightAccessor pLevel) { + return this.delegate.getFirstOccupiedHeight(pX, pZ, pType, pLevel); + } + + @Override + public boolean hasStronghold(ChunkPos pPos) { + return this.delegate.hasStronghold(pPos); + } + + @Override + public WeightedRandomList getMobsAt(Biome pBiome, StructureFeatureManager pStructureFeatureManager, MobCategory pCategory, BlockPos pPos) { + return this.delegate.getMobsAt(pBiome, pStructureFeatureManager, pCategory, pPos); + } + + @Override + public BiomeSource getBiomeSource() { + return this.delegate.getBiomeSource(); + } + + @Override + public int getSpawnHeight(LevelHeightAccessor pLevel) { + return this.delegate.getSpawnHeight(pLevel); + } + + @Override + public StructureSettings getSettings() { + return this.delegate.getSettings(); + } + + @Override + public void applyBiomeDecoration(WorldGenLevel pLevel, ChunkAccess pChunk, StructureFeatureManager pStructureFeatureManager) { + this.delegate.applyBiomeDecoration(pLevel, pChunk, pStructureFeatureManager); + } + + @Nullable + @Override + public BlockPos findNearestMapFeature(ServerLevel pLevel, StructureFeature pStructure, BlockPos pPos, int pSearchRadius, boolean pSkipKnownStructures) { + return this.delegate.findNearestMapFeature(pLevel, pStructure, pPos, pSearchRadius, pSkipKnownStructures); + } + + @Override + public CompletableFuture createBiomes(Registry p_196743_, Executor p_196744_, Blender p_196745_, StructureFeatureManager p_196746_, ChunkAccess p_196747_) { + return this.delegate.createBiomes(p_196743_, p_196744_, p_196745_, p_196746_, p_196747_); + } + + @Override + protected Codec codec() { + return CODEC; + } + + @Override + public ChunkGenerator withSeed(long pSeed) { + return new ModChunkGenerator(this.delegate.withSeed(pSeed)); + } + + @Override + public Climate.Sampler climateSampler() { + return this.delegate.climateSampler(); + } + + @Override + public void applyCarvers(WorldGenRegion pLevel, long pSeed, BiomeManager pBiomeManager, StructureFeatureManager pStructureFeatureManager, ChunkAccess pChunk, GenerationStep.Carving pStep) { + this.delegate.applyCarvers(pLevel, pSeed, pBiomeManager, pStructureFeatureManager, pChunk, pStep); + } + + @Override + public void buildSurface(WorldGenRegion pLevel, StructureFeatureManager pStructureFeatureManager, ChunkAccess pChunk) { + this.delegate.buildSurface(pLevel, pStructureFeatureManager, pChunk); + } + + @Override + public void spawnOriginalMobs(WorldGenRegion pLevel) { + this.delegate.spawnOriginalMobs(pLevel); + } + + @Override + public int getGenDepth() { + return this.delegate.getGenDepth(); + } + + @Override + public CompletableFuture fillFromNoise(Executor p_187748_, Blender p_187749_, StructureFeatureManager p_187750_, ChunkAccess p_187751_) { + return this.delegate.fillFromNoise(p_187748_, p_187749_, p_187750_, p_187751_); + } + + @Override + public int getSeaLevel() { + return this.delegate.getSeaLevel(); + } + + @Override + public int getMinY() { + return this.delegate.getMinY(); + } + + @Override + public int getBaseHeight(int pX, int pZ, Heightmap.Types pType, LevelHeightAccessor pLevel) { + return this.delegate.getBaseHeight(pX, pZ, pType, pLevel); + } + + @Override + public NoiseColumn getBaseColumn(int pX, int pZ, LevelHeightAccessor pLevel) { + return this.delegate.getBaseColumn(pX, pZ, pLevel); + } +} diff --git a/src/main/java/com/xekr/ironstars/world/PixelTransformer.java b/src/main/java/com/xekr/ironstars/world/PixelTransformer.java new file mode 100644 index 0000000..3033327 --- /dev/null +++ b/src/main/java/com/xekr/ironstars/world/PixelTransformer.java @@ -0,0 +1,5 @@ +package com.xekr.ironstars.world; + +public interface PixelTransformer { + int apply(int p_77076_, int p_77077_); +} \ No newline at end of file diff --git a/src/main/java/com/xekr/ironstars/world/WorldGenerator.java b/src/main/java/com/xekr/ironstars/world/WorldGenerator.java new file mode 100644 index 0000000..ebeb58f --- /dev/null +++ b/src/main/java/com/xekr/ironstars/world/WorldGenerator.java @@ -0,0 +1,297 @@ +package com.xekr.ironstars.world; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.gson.JsonElement; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.Encoder; +import com.mojang.serialization.JsonOps; +import com.mojang.serialization.Lifecycle; +import com.xekr.ironstars.IronStars; +import com.xekr.ironstars.IronStarsUtil; +import com.xekr.ironstars.registry.AllBiomes; +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; +import net.minecraft.data.BuiltinRegistries; +import net.minecraft.data.DataGenerator; +import net.minecraft.data.DataProvider; +import net.minecraft.data.HashCache; +import net.minecraft.resources.RegistryWriteOps; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.CubicSpline; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.biome.AmbientMoodSettings; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeGenerationSettings; +import net.minecraft.world.level.biome.BiomeSpecialEffects; +import net.minecraft.world.level.biome.MobSpawnSettings; +import net.minecraft.world.level.biome.TerrainShaper; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.dimension.DimensionType; +import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; +import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; +import net.minecraft.world.level.levelgen.NoiseSamplingSettings; +import net.minecraft.world.level.levelgen.NoiseSettings; +import net.minecraft.world.level.levelgen.NoiseSlider; +import net.minecraft.world.level.levelgen.StructureSettings; +import net.minecraft.world.level.levelgen.SurfaceRules; +import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.IForgeRegistryEntry; +import net.minecraftforge.registries.RegistryManager; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.OptionalLong; +import java.util.function.Supplier; + +public class WorldGenerator extends RegistryWriteOps implements DataProvider { + private final DataGenerator generator; + + private HashCache cache; + private final HashSet SerializeCache = new HashSet<>(); + + public WorldGenerator(DataGenerator generator) { + super(JsonOps.INSTANCE, new RegistryAccess.RegistryHolder()); + this.generator = generator; + } + + private void generate() { + // TODO: 雕刻器还没写 +// ConfiguredWorldCarvers.registerConfigurations(this.registryAccess.registryOrThrow(Registry.CONFIGURED_CARVER_REGISTRY)); + + Map biomes = this.getBiomes(); + biomes.forEach((rl, biome) -> this.registryAccess.registry(Registry.BIOME_REGISTRY).ifPresent(reg -> Registry.register(reg, rl, biome))); + biomes.forEach((rl, biome) -> this.serialize(Registry.BIOME_REGISTRY, rl, biome, Biome.DIRECT_CODEC)); + + this.getDimensions().forEach((rl, dimension) -> this.serialize(Registry.LEVEL_STEM_REGISTRY, rl, dimension, LevelStem.CODEC)); + } + + public void serialize(ResourceKey> resourceType, ResourceLocation resourceLocation, T resource, Encoder encoder) { + if (SerializeCache.contains(resource)) { + IronStars.LOGGER.debug("Please do not serialize '" + resourceLocation + "' repeatedly!"); + return; + } + SerializeCache.add(resource); + Optional output = this.withEncoder(encoder).apply(resource).setLifecycle(Lifecycle.experimental()) + .resultOrPartial(error -> IronStars.LOGGER.error("Not serialized object " + resourceLocation + " with " + error)); + if (output.isPresent()) { + try { + Path path = this.generator.getOutputFolder().resolve("data").resolve(resourceLocation.getNamespace()) + .resolve(resourceType.location().getPath()).resolve(resourceLocation.getPath() + ".json"); + save(resourceType, cache, output.get(), path); + } catch (IOException e) { + IronStars.LOGGER.error("Could not save '" + resourceLocation + "' (Resource Type '" + resourceType.location() + "')", e); + } + } + } + + private void save(ResourceKey key, HashCache cache, JsonElement dynamic, Path pathIn) throws IOException { + if (key == Registry.LEVEL_STEM_REGISTRY) dynamic.getAsJsonObject().get("generator").getAsJsonObject() + .get("wrapped_generator").getAsJsonObject().get("biome_source").getAsJsonObject().remove("seed"); + String jsonString = IronStarsUtil.GSON.toJson(dynamic); + String result = SHA1.hashUnencodedChars(jsonString).toString(); + if (!Objects.equals(cache.getHash(pathIn), result) || !Files.exists(pathIn)) { + Files.createDirectories(pathIn.getParent()); + try (BufferedWriter bufferedwriter = Files.newBufferedWriter(pathIn)) { + bufferedwriter.write(jsonString); + } + } + cache.putNew(pathIn, result); + } + + @SuppressWarnings({"rawtypes"}) + protected static > Optional getLocationFromRegistry(Registry registry, ResourceKey key, E element) { + T t = getRegistry(registry, key); + return t != null ? getLocationFromRegistry(t, element) : Optional.empty(); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + protected static T getRegistry(Registry registry, ResourceKey key) { + return (T) registry.get(key); + } + + protected static > Optional getLocationFromRegistry(T registry, E element) { + return registry.getResourceKey(element).map(ResourceKey::location); + } + + @Override + @SuppressWarnings({"rawtypes", "unchecked"}) + protected DataResult encode(E pElement, JsonElement pPrefix, ResourceKey> pRegistryKey, Codec pElementCodec) { + Optional key = Optional.empty(); + if (pElement instanceof IForgeRegistryEntry) + key = Optional.ofNullable(((IForgeRegistryEntry) pElement).getRegistryName()); + if (key.isEmpty()) { + try { + key = getLocationFromRegistry(this.registryAccess.registryOrThrow(pRegistryKey), pElement); + } catch (Throwable ignored) {} + } + if (key.isEmpty()) key = getLocationFromRegistry(BuiltinRegistries.REGISTRY, pRegistryKey, pElement); + if (key.isEmpty()) key = getLocationFromRegistry(Registry.REGISTRY, pRegistryKey, pElement); + if (key.isEmpty() && pElement instanceof IForgeRegistryEntry entry) { + ResourceLocation location = entry.getRegistryName(); + if (location == null) { + IForgeRegistry forgeRegistry = RegistryManager.ACTIVE.getRegistry(pRegistryKey.location()); + key = Optional.ofNullable(forgeRegistry.getKey(entry)); + }else key = Optional.of(location); + } + if (key.isPresent()) { + ResourceLocation location = key.get(); + if (IronStars.ID.equals(location.getNamespace())) + this.serialize(pRegistryKey, location, pElement, pElementCodec); + return ResourceLocation.CODEC.encode(key.get(), this.delegate, pPrefix); + } + return pElementCodec.encode(pElement, this, pPrefix); + } + + @Override + public void run(HashCache pCache) { + this.cache = pCache; + generate(); + } + + @Override + public String getName() { + return "Moon World"; + } + + @SuppressWarnings("UnusedReturnValue") + protected T getOrCreateInRegistry(ResourceKey> registryKey, ResourceKey> resourceKey, ResourceLocation pLocation, Supplier resourceCreator) { + Registry registry = this.registryAccess.registryOrThrow(registryKey); + ResourceKey resourceKey1 = ResourceKey.create(resourceKey, pLocation); + T resourceSaved = getRegistry(registry, resourceKey1); + return resourceSaved != null ? resourceSaved : Registry.register(registry, resourceKey1.location(), resourceCreator.get()); + } + + /* + * NoiseGeneratorSettings + * structureSettings StructureSettings + * noiseSettings NoiseSettings + * defaultBlock BlockState + * defaultFluid BlockState + * rules SurfaceRules.RuleSource + * seaLevel int + * disableMobGeneration boolean + * aquifersEnabled boolean + * noiseCavesEnabled boolean + * oreVeinsEnabled boolean + * noodleCavesEnabled boolean + */ + private Map getDimensions() { + NoiseGeneratorSettings dimensionSettings = new NoiseGeneratorSettings( + new StructureSettings(Optional.empty(), ImmutableMap.of()), + NoiseSettings.create( + -32, + 256, + new NoiseSamplingSettings(0.9999999814507745D, 0.9999999814507745D, 80.0D, 160.0D), + new NoiseSlider(-10, 3, 0), + new NoiseSlider(15, 3, 0), + 1, + 2, + true, + true, + false, + new TerrainShaper(CubicSpline.constant(0.0F), CubicSpline.constant(0.0F), CubicSpline.constant(0.0F)) + ), + Blocks.STONE.defaultBlockState(), + Blocks.WATER.defaultBlockState(), + tfSurface(), + 0, + false, + false, + false, + false, + false, + false + ); + + this.getOrCreateInRegistry(Registry.NOISE_GENERATOR_SETTINGS_REGISTRY, Registry.NOISE_GENERATOR_SETTINGS_REGISTRY, IronStars.id("moon_noise_config"), () -> dimensionSettings); + + + NoiseBasedChunkGenerator chunkGen = new NoiseBasedChunkGenerator(RegistryAccess.builtin().registryOrThrow(Registry.NOISE_REGISTRY), new BiomeProvider(0L, new MappedRegistry<>(Registry.BIOME_REGISTRY, Lifecycle.experimental())), 0L, () -> dimensionSettings); + + final DimensionType dimensionType = DimensionType.create( + OptionalLong.of(13000L), + true, + false, + false, + true, + 0.125D, + false, + false, + true, + true, + false, + -32, + 32+256, + 32+256, + new ResourceLocation("infiniburn_overworld"), + IronStars.id("renderer"), + 0f + ); + + this.getOrCreateInRegistry(Registry.DIMENSION_TYPE_REGISTRY, Registry.DIMENSION_TYPE_REGISTRY, IronStars.id("moon_type"), () -> dimensionType); + + return ImmutableMap.of( + IronStars.id("twilightforest"), new LevelStem(() -> dimensionType, new ModChunkGenerator(chunkGen, true)) + ); + } + + public static SurfaceRules.RuleSource tfSurface() { + + ImmutableList.Builder builder = ImmutableList.builder(); + return SurfaceRules.sequence(builder.build().toArray(SurfaceRules.RuleSource[]::new)); + } + + private Map getBiomes() { + + BiomeSpecialEffects.Builder biomeAmbience = new BiomeSpecialEffects.Builder() + .fogColor(0xC0FFD8) + .waterColor(0x3F76E4) + .waterFogColor(0x050533) + .skyColor(0x20224A) + .ambientMoodSound(AmbientMoodSettings.LEGACY_CAVE_SETTINGS); + + MobSpawnSettings.Builder spawnInfo = new MobSpawnSettings.Builder(); + + spawnInfo.creatureGenerationProbability(0.1f); + + spawnInfo.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.CHICKEN, 10, 4, 4)); + spawnInfo.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.WOLF, 5, 4, 4)); + + spawnInfo.addSpawn(MobCategory. MONSTER, new MobSpawnSettings.SpawnerData(EntityType.SPIDER, 10, 4, 4)); + spawnInfo.addSpawn(MobCategory. MONSTER, new MobSpawnSettings.SpawnerData(EntityType.ZOMBIE, 10, 4, 4)); + spawnInfo.addSpawn(MobCategory. MONSTER, new MobSpawnSettings.SpawnerData(EntityType.SKELETON, 10, 4, 4)); + spawnInfo.addSpawn(MobCategory. MONSTER, new MobSpawnSettings.SpawnerData(EntityType.CREEPER, 1, 4, 4)); + spawnInfo.addSpawn(MobCategory. MONSTER, new MobSpawnSettings.SpawnerData(EntityType.SLIME, 10, 4, 4)); + spawnInfo.addSpawn(MobCategory. MONSTER, new MobSpawnSettings.SpawnerData(EntityType.ENDERMAN, 1, 1, 4)); + + spawnInfo.addSpawn(MobCategory. MONSTER, new MobSpawnSettings.SpawnerData(EntityType.BAT, 10, 1, 2)); + + BiomeGenerationSettings.Builder biomeGenerationSettings = new BiomeGenerationSettings.Builder(); + Biome biome = new Biome.BiomeBuilder() + .precipitation(Biome.Precipitation.RAIN) + .biomeCategory(Biome.BiomeCategory.FOREST) + .temperature(0.5F) + .downfall(0.5F) + .specialEffects(biomeAmbience.build()) + .mobSpawnSettings(spawnInfo.build()) + .generationSettings(biomeGenerationSettings.build()) + .temperatureAdjustment(Biome.TemperatureModifier.NONE) + .build(); + + ImmutableMap.Builder builder = ImmutableMap.builder(); + return builder.put(AllBiomes.MOON.location(), biome).build(); + } + +} diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index e69de29..5ad0ee0 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -0,0 +1,6 @@ +protected net.minecraft.resources.RegistryWriteOps (Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/core/RegistryAccess;)V +protected net.minecraft.resources.RegistryWriteOps f_179906_ +public net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator f_64316_ +public net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator f_64333_ +public net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator f_158382_ +public net.minecraft.world.level.chunk.ChunkGenerator f_62140_ \ No newline at end of file diff --git a/src/main/resources/ironstars.mixins.json b/src/main/resources/ironstars.mixins.json index 372d33e..5f8b3d9 100644 --- a/src/main/resources/ironstars.mixins.json +++ b/src/main/resources/ironstars.mixins.json @@ -5,6 +5,7 @@ "compatibilityLevel": "JAVA_8", "refmap": "mixins.refmap.json", "mixins": [ + "AnvilBlockMixin", "ItemEntityMixin", "LightingBoltMixin" ],