-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(Horrible) temporary work-around for arch loom getting common mixin r…
…emap wrong for Forge
- Loading branch information
1 parent
b6e87e5
commit d34921a
Showing
12 changed files
with
675 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
forge/src/main/java/com/terraformersmc/biolith/impl/mixin/MixinBiomeSource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.terraformersmc.biolith.impl.mixin; | ||
|
||
import com.terraformersmc.biolith.impl.Biolith; | ||
import com.terraformersmc.biolith.impl.biome.InterfaceBiomeSource; | ||
import net.minecraft.registry.entry.RegistryEntry; | ||
import net.minecraft.world.biome.source.BiomeSource; | ||
import net.minecraft.world.dimension.DimensionType; | ||
import org.jetbrains.annotations.Nullable; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
|
||
@Mixin(BiomeSource.class) | ||
public class MixinBiomeSource implements InterfaceBiomeSource { | ||
private RegistryEntry<DimensionType> biolith$dimensionTypeEntry; | ||
|
||
@Override | ||
public @Nullable RegistryEntry<DimensionType> biolith$getDimensionType() { | ||
return biolith$dimensionTypeEntry; | ||
} | ||
|
||
@Override | ||
public void biolith$setDimensionType(RegistryEntry<DimensionType> dimensionTypeEntry) { | ||
if (biolith$dimensionTypeEntry != null && | ||
biolith$dimensionTypeEntry.hasKeyAndValue() && dimensionTypeEntry.hasKeyAndValue() && | ||
!biolith$dimensionTypeEntry.getKey().orElseThrow().equals(dimensionTypeEntry.getKey().orElseThrow())) { | ||
Biolith.LOGGER.warn("Dimension Type modified: from '{}' to '{}'", | ||
biolith$dimensionTypeEntry.getKey().orElseThrow(), dimensionTypeEntry.getKey().orElseThrow()); | ||
} | ||
|
||
biolith$dimensionTypeEntry = dimensionTypeEntry; | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
forge/src/main/java/com/terraformersmc/biolith/impl/mixin/MixinChunkGeneratorSettings.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.terraformersmc.biolith.impl.mixin; | ||
|
||
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings; | ||
import net.minecraft.world.gen.surfacebuilder.MaterialRules; | ||
import org.spongepowered.asm.mixin.Final; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Mutable; | ||
import org.spongepowered.asm.mixin.gen.Accessor; | ||
|
||
@Mixin(ChunkGeneratorSettings.class) | ||
public interface MixinChunkGeneratorSettings { | ||
@Final | ||
@Mutable | ||
@Accessor("surfaceRule") | ||
void biolith$setSurfaceRule(MaterialRules.MaterialRule ruleSource); | ||
} |
38 changes: 38 additions & 0 deletions
38
forge/src/main/java/com/terraformersmc/biolith/impl/mixin/MixinDataPackContents.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.terraformersmc.biolith.impl.mixin; | ||
|
||
import com.llamalad7.mixinextras.injector.ModifyReturnValue; | ||
import com.terraformersmc.biolith.impl.data.BiomePlacementLoader; | ||
import com.terraformersmc.biolith.impl.data.SurfaceGenerationLoader; | ||
import net.minecraft.registry.DynamicRegistryManager; | ||
import net.minecraft.resource.ResourceReloader; | ||
import net.minecraft.resource.featuretoggle.FeatureSet; | ||
import net.minecraft.server.DataPackContents; | ||
import net.minecraft.server.command.CommandManager; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Unique; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Inject; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
|
||
import java.util.List; | ||
import java.util.stream.Stream; | ||
|
||
@Mixin(DataPackContents.class) | ||
public abstract class MixinDataPackContents { | ||
@Unique | ||
private BiomePlacementLoader biomePlacementLoader; | ||
@Unique | ||
private SurfaceGenerationLoader surfaceGenerationLoader; | ||
|
||
@Inject(method = "<init>", at = @At("TAIL")) | ||
private void biolith$addDataPackContents(DynamicRegistryManager.Immutable dynamicRegistryManager, FeatureSet enabledFeatures, CommandManager.RegistrationEnvironment environment, int functionPermissionLevel, CallbackInfo ci) { | ||
biomePlacementLoader = new BiomePlacementLoader(); | ||
surfaceGenerationLoader = new SurfaceGenerationLoader(); | ||
} | ||
|
||
@ModifyReturnValue(method = "getContents", at = @At("RETURN")) | ||
@SuppressWarnings("unused") | ||
private List<ResourceReloader> biolith$addReloadersToContents(List<ResourceReloader> original) { | ||
return Stream.concat(original.stream(), Stream.of(biomePlacementLoader, surfaceGenerationLoader)).toList(); | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
forge/src/main/java/com/terraformersmc/biolith/impl/mixin/MixinDimensionOptions.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.terraformersmc.biolith.impl.mixin; | ||
|
||
import net.minecraft.registry.entry.RegistryEntry; | ||
import net.minecraft.world.dimension.DimensionOptions; | ||
import net.minecraft.world.dimension.DimensionType; | ||
import net.minecraft.world.gen.chunk.ChunkGenerator; | ||
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(DimensionOptions.class) | ||
public class MixinDimensionOptions { | ||
@Inject(method = "<init>", at = @At("RETURN")) | ||
private void biolith$storeDimensionTypeToBiomeSource(RegistryEntry<DimensionType> dimensionTypeEntry, ChunkGenerator chunkGenerator, CallbackInfo ci) { | ||
chunkGenerator.getBiomeSource().biolith$setDimensionType(dimensionTypeEntry); | ||
} | ||
} |
93 changes: 93 additions & 0 deletions
93
forge/src/main/java/com/terraformersmc/biolith/impl/mixin/MixinMinecraftServer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package com.terraformersmc.biolith.impl.mixin; | ||
|
||
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.server.MinecraftServer; | ||
import net.minecraft.server.WorldGenerationProgressListener; | ||
import net.minecraft.server.world.ServerWorld; | ||
import net.minecraft.world.World; | ||
import net.minecraft.world.dimension.DimensionOptions; | ||
import net.minecraft.world.dimension.DimensionType; | ||
import net.minecraft.world.dimension.DimensionTypes; | ||
import net.minecraft.world.gen.chunk.ChunkGenerator; | ||
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings; | ||
import net.minecraft.world.gen.chunk.NoiseChunkGenerator; | ||
import net.minecraft.world.gen.surfacebuilder.MaterialRules; | ||
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.Map; | ||
import java.util.Optional; | ||
import java.util.stream.Stream; | ||
|
||
@Mixin(MinecraftServer.class) | ||
public abstract class MixinMinecraftServer { | ||
@Shadow | ||
@Final | ||
private Map<RegistryKey<World>, ServerWorld> worlds; | ||
|
||
@WrapOperation(method = "<init>", at = @At( | ||
value = "INVOKE", | ||
target = "Lnet/minecraft/registry/CombinedDynamicRegistries;getCombinedRegistryManager()Lnet/minecraft/registry/DynamicRegistryManager$Immutable;", | ||
opcode = Opcodes.PUTFIELD, | ||
ordinal = 0 | ||
)) | ||
@SuppressWarnings("unused") | ||
private DynamicRegistryManager.Immutable biolith$earlyCaptureRegistries(CombinedDynamicRegistries<ServerDynamicRegistryType> instance, Operation<DynamicRegistryManager.Immutable> original) { | ||
// This capture updates any registry manager we scraped previously with the final version. | ||
BiomeCoordinator.setRegistryManager(instance); | ||
|
||
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) { | ||
MaterialRules.MaterialRule[] rulesType = new MaterialRules.MaterialRule[0]; | ||
|
||
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; | ||
} | ||
} | ||
|
||
// 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(); | ||
//ChunkGenerator chunkGenerator = ((ServerChunkManager) world.getChunkManager()).threadedAnvilChunkStorage.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))); | ||
} | ||
} | ||
} | ||
} | ||
} |
115 changes: 115 additions & 0 deletions
115
forge/src/main/java/com/terraformersmc/biolith/impl/mixin/MixinMultiNoiseBiomeSource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package com.terraformersmc.biolith.impl.mixin; | ||
|
||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation; | ||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; | ||
import com.mojang.datafixers.util.Either; | ||
import com.mojang.datafixers.util.Pair; | ||
import com.terraformersmc.biolith.impl.biome.BiolithFittestNodes; | ||
import com.terraformersmc.biolith.impl.biome.BiomeCoordinator; | ||
import com.terraformersmc.biolith.impl.compat.BiolithCompat; | ||
import com.terraformersmc.biolith.impl.compat.VanillaCompat; | ||
import com.terraformersmc.biolith.impl.platform.Services; | ||
import net.minecraft.registry.entry.RegistryEntry; | ||
import net.minecraft.world.biome.Biome; | ||
import net.minecraft.world.biome.source.BiomeSource; | ||
import net.minecraft.world.biome.source.MultiNoiseBiomeSource; | ||
import net.minecraft.world.biome.source.MultiNoiseBiomeSourceParameterList; | ||
import net.minecraft.world.biome.source.util.MultiNoiseUtil; | ||
import net.minecraft.world.dimension.DimensionTypes; | ||
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; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.function.Function; | ||
|
||
// Inject before TerraBlender so we can ensure our tree search and placement overrides get used. | ||
@Mixin(value = MultiNoiseBiomeSource.class, priority = 900) | ||
public abstract class MixinMultiNoiseBiomeSource extends BiomeSource { | ||
@Shadow | ||
protected abstract MultiNoiseUtil.Entries<RegistryEntry<Biome>> getBiomeEntries(); | ||
|
||
private MultiNoiseUtil.Entries<RegistryEntry<Biome>> biolith$biomeEntries; | ||
|
||
// Inject noise points the first time somebody requests them. | ||
@WrapOperation( | ||
method = "getBiomeEntries", | ||
at = @At(value = "INVOKE", target = "Lcom/mojang/datafixers/util/Either;map(Ljava/util/function/Function;Ljava/util/function/Function;)Ljava/lang/Object;") | ||
) | ||
@SuppressWarnings("unused") | ||
private Object biolith$injectEntries(Either<MultiNoiseUtil.Entries<RegistryEntry<Biome>>, RegistryEntry<MultiNoiseBiomeSourceParameterList>> instance, Function<MultiNoiseUtil.Entries<RegistryEntry<Biome>>, MultiNoiseUtil.Entries<RegistryEntry<Biome>>> leftMap, Function<RegistryEntry<MultiNoiseBiomeSourceParameterList>, MultiNoiseUtil.Entries<RegistryEntry<Biome>>> rightMap, Operation<Object> original) { | ||
synchronized (this) { | ||
// Only compute this once, since our version is more expensive than Mojang's. | ||
if (biolith$biomeEntries == null) { | ||
// Mojang does the exact same cast on the return of this operation. | ||
//noinspection unchecked | ||
MultiNoiseUtil.Entries<RegistryEntry<Biome>> originalEntries = | ||
(MultiNoiseUtil.Entries<RegistryEntry<Biome>>) original.call(instance, leftMap, rightMap); | ||
|
||
if (this.biolith$getDimensionType().matchesKey(DimensionTypes.OVERWORLD)) { | ||
List<Pair<MultiNoiseUtil.NoiseHypercube, RegistryEntry<Biome>>> parameterList = new ArrayList<>(256); | ||
|
||
// Remove any biomes matching removals | ||
originalEntries.getEntries().stream() | ||
.filter(BiomeCoordinator.OVERWORLD::removalFilter) | ||
.forEach(parameterList::add); | ||
|
||
// Add all biomes from additions, replacements, and sub-biome requests | ||
BiomeCoordinator.OVERWORLD.writeBiomeEntries(parameterList::add); | ||
|
||
biolith$biomeEntries = new MultiNoiseUtil.Entries<>(parameterList); | ||
} else if (this.biolith$getDimensionType().matchesKey(DimensionTypes.THE_NETHER)) { | ||
List<Pair<MultiNoiseUtil.NoiseHypercube, RegistryEntry<Biome>>> parameterList = new ArrayList<>(64); | ||
|
||
// Remove any biomes matching removals | ||
originalEntries.getEntries().stream() | ||
.filter(BiomeCoordinator.NETHER::removalFilter) | ||
.forEach(parameterList::add); | ||
|
||
// Add all biomes from additions, replacements, and sub-biome requests | ||
BiomeCoordinator.NETHER.writeBiomeEntries(parameterList::add); | ||
|
||
biolith$biomeEntries = new MultiNoiseUtil.Entries<>(parameterList); | ||
} else { | ||
biolith$biomeEntries = originalEntries; | ||
} | ||
} | ||
} // synchronized (this) | ||
|
||
return biolith$biomeEntries; | ||
} | ||
|
||
// We calculate the vanilla/datapack biome, then we apply any overlays. | ||
@Inject(method = "getBiome", at = @At("HEAD"), cancellable = true) | ||
private void biolith$getBiome(int x, int y, int z, MultiNoiseUtil.MultiNoiseSampler noise, CallbackInfoReturnable<RegistryEntry<Biome>> cir) { | ||
MultiNoiseUtil.NoiseValuePoint noisePoint = noise.sample(x, y, z); | ||
BiolithFittestNodes<RegistryEntry<Biome>> fittestNodes = null; | ||
|
||
// Find the biome via TerraBlender if available. | ||
if (BiolithCompat.COMPAT_TERRABLENDER) { | ||
fittestNodes = Services.PLATFORM.getTerraBlenderCompat().getBiome(x, y, z, noisePoint, getBiomeEntries()); | ||
} | ||
|
||
// Find the biome via Vanilla (including datapacks) if none was provided by TerraBlender. | ||
if (fittestNodes == null) { | ||
fittestNodes = VanillaCompat.getBiome(noisePoint, getBiomeEntries()); | ||
} | ||
|
||
// Apply biome overlays. | ||
if (this.biolith$getDimensionType().matchesKey(DimensionTypes.OVERWORLD)) { | ||
cir.setReturnValue(BiomeCoordinator.OVERWORLD.getReplacement(x, y, z, noisePoint, fittestNodes)); | ||
} else if (this.biolith$getDimensionType().matchesKey(DimensionTypes.THE_NETHER)) { | ||
cir.setReturnValue(BiomeCoordinator.NETHER.getReplacement(x, y, z, noisePoint, fittestNodes)); | ||
} else { | ||
cir.setReturnValue(fittestNodes.ultimate().value); | ||
} | ||
} | ||
|
||
@Override | ||
public MultiNoiseUtil.Entries<RegistryEntry<Biome>> biolith$getBiomeEntries() { | ||
return biolith$biomeEntries; | ||
} | ||
} |
Oops, something went wrong.