Skip to content

Commit

Permalink
Move surface rule injection earlier to try and fix NeoForge.
Browse files Browse the repository at this point in the history
- Fix 5x5 chunk area missing surface rules at spawn on NeoForge
  • Loading branch information
gniftygnome committed Feb 5, 2025
1 parent 0381a3c commit e8e2309
Showing 1 changed file with 39 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
import com.google.common.collect.Streams;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import com.terraformersmc.biolith.impl.biome.BiomeCoordinator;
import com.terraformersmc.biolith.impl.surface.SurfaceRuleCollector;
import net.minecraft.registry.*;
import net.minecraft.registry.CombinedDynamicRegistries;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.ServerDynamicRegistryType;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.WorldGenerationProgressListener;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.random.RandomSequencesState;
import net.minecraft.world.World;
import net.minecraft.world.dimension.DimensionOptions;
import net.minecraft.world.dimension.DimensionType;
Expand All @@ -18,18 +21,21 @@
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
import net.minecraft.world.gen.chunk.NoiseChunkGenerator;
import net.minecraft.world.gen.surfacebuilder.MaterialRules;
import net.minecraft.world.level.ServerWorldProperties;
import net.minecraft.world.level.storage.LevelStorage;
import net.minecraft.world.spawner.SpecialSpawner;
import org.jetbrains.annotations.Nullable;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Final;
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.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Executor;
import java.util.stream.Stream;

@Mixin(MinecraftServer.class)
Expand All @@ -52,41 +58,40 @@ public abstract class MixinMinecraftServer {
return original.call(instance);
}

@Inject(method = "createWorlds", at = @At(value = "RETURN"), locals = LocalCapture.CAPTURE_FAILHARD)
private void biolith$prependSurfaceRules(WorldGenerationProgressListener worldGenerationProgressListener, CallbackInfo ci, @Local Registry<DimensionOptions> dimensionOptionsRegistry) {
@WrapOperation(method = "createWorlds", at = @At(
value = "NEW",
target = "net/minecraft/server/world/ServerWorld"
))
@SuppressWarnings("unused")
private ServerWorld biolith$prependSurfaceRules(MinecraftServer server, Executor workerExecutor, LevelStorage.Session session, ServerWorldProperties properties, RegistryKey<World> worldKey, DimensionOptions dimensionOptions, WorldGenerationProgressListener worldGenerationProgressListener, boolean debugWorld, long seed, List<SpecialSpawner> spawners, boolean shouldTickTime, @Nullable RandomSequencesState randomSequencesState, Operation<ServerWorld> operation) {
Optional<RegistryKey<DimensionType>> dimensionKey = dimensionOptions.dimensionTypeEntry().getKey();
MaterialRules.MaterialRule[] rulesType = new MaterialRules.MaterialRule[0];
SurfaceRuleCollector surfaceRuleCollector = null;

for (World world : worlds.values()) {
DimensionOptions dimensionOptions = null;
SurfaceRuleCollector surfaceRuleCollector = null;
Optional<RegistryKey<DimensionType>> dimensionKey = world.getDimensionEntry().getKey();

if (dimensionKey.isPresent()) {
if (DimensionTypes.OVERWORLD.equals(dimensionKey.get())) {
dimensionOptions = dimensionOptionsRegistry.get(DimensionOptions.OVERWORLD);
surfaceRuleCollector = SurfaceRuleCollector.OVERWORLD;
} else if (DimensionTypes.THE_NETHER.equals(dimensionKey.get())) {
dimensionOptions = dimensionOptionsRegistry.get(DimensionOptions.NETHER);
surfaceRuleCollector = SurfaceRuleCollector.NETHER;
} else if (DimensionTypes.THE_END.equals(dimensionKey.get())) {
dimensionOptions = dimensionOptionsRegistry.get(DimensionOptions.END);
surfaceRuleCollector = SurfaceRuleCollector.END;
}
if (dimensionKey.isPresent()) {
if (DimensionTypes.OVERWORLD.equals(dimensionKey.get())) {
surfaceRuleCollector = SurfaceRuleCollector.OVERWORLD;
} else if (DimensionTypes.THE_NETHER.equals(dimensionKey.get())) {
surfaceRuleCollector = SurfaceRuleCollector.NETHER;
} else if (DimensionTypes.THE_END.equals(dimensionKey.get())) {
surfaceRuleCollector = SurfaceRuleCollector.END;
}
}

// TODO: Consider whether we need to guard against modifying the same ChunkGeneratorSettings more than once...
if (dimensionOptions != null && surfaceRuleCollector.getRuleCount() > 0) {
ChunkGenerator chunkGenerator = dimensionOptions.chunkGenerator();
if (chunkGenerator instanceof NoiseChunkGenerator noiseChunkGenerator) {
ChunkGeneratorSettings chunkGeneratorSettings = noiseChunkGenerator.getSettings().value();
// TODO: Consider whether we need to guard against modifying the same ChunkGeneratorSettings more than once...
if (surfaceRuleCollector != null && surfaceRuleCollector.getRuleCount() > 0) {
ChunkGenerator chunkGenerator = dimensionOptions.chunkGenerator();
if (chunkGenerator instanceof NoiseChunkGenerator noiseChunkGenerator) {
ChunkGeneratorSettings chunkGeneratorSettings = noiseChunkGenerator.getSettings().value();

((MixinChunkGeneratorSettings)(Object) chunkGeneratorSettings).biolith$setSurfaceRule(
MaterialRules.sequence(Streams.concat(
Arrays.stream(surfaceRuleCollector.getAll()),
Stream.of(chunkGeneratorSettings.surfaceRule()))
.toList().toArray(rulesType)));
}
((MixinChunkGeneratorSettings)(Object) chunkGeneratorSettings).biolith$setSurfaceRule(
MaterialRules.sequence(Streams.concat(
Arrays.stream(surfaceRuleCollector.getAll()),
Stream.of(chunkGeneratorSettings.surfaceRule()))
.toList().toArray(rulesType)));
}
}

return operation.call(server, workerExecutor, session, properties, worldKey, dimensionOptions, worldGenerationProgressListener, debugWorld, seed, spawners, shouldTickTime, randomSequencesState);
}
}

0 comments on commit e8e2309

Please sign in to comment.