diff --git a/build.gradle.kts b/build.gradle.kts index 3670202fc4..b99cab6db6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,8 +1,8 @@ preRelease(true) -versionProjects(":common:api", version("6.0.1")) -versionProjects(":common:implementation", version("6.0.1")) -versionProjects(":platforms", version("6.0.1")) +versionProjects(":common:api", version("6.1.0")) +versionProjects(":common:implementation", version("6.1.0")) +versionProjects(":platforms", version("6.1.0")) allprojects { diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 06ce4a579d..07713bb5be 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -3,6 +3,15 @@ plugins { kotlin("jvm") version embeddedKotlinVersion } +buildscript { + configurations.all { + resolutionStrategy { + force("org.ow2.asm:asm:9.3") // TODO: remove when ShadowJar updates ASM version + force("org.ow2.asm:asm-commons:9.3") + } + } +} + repositories { mavenCentral() gradlePluginPortal() @@ -11,8 +20,8 @@ repositories { dependencies { implementation("gradle.plugin.com.github.jengelman.gradle.plugins:shadow:+") - implementation("org.ow2.asm:asm:9.2") - implementation("org.ow2.asm:asm-tree:9.2") + implementation("org.ow2.asm:asm:9.3") + implementation("org.ow2.asm:asm-tree:9.3") implementation("com.dfsek.tectonic:common:4.2.0") implementation("org.yaml:snakeyaml:1.27") } \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/AddonConfig.kt b/buildSrc/src/main/kotlin/AddonConfig.kt index 96221b3a78..ec585ba8e6 100644 --- a/buildSrc/src/main/kotlin/AddonConfig.kt +++ b/buildSrc/src/main/kotlin/AddonConfig.kt @@ -3,7 +3,6 @@ import java.io.File import java.util.function.Predicate import org.gradle.api.Project import org.gradle.api.Task -import org.gradle.jvm.tasks.Jar import org.gradle.kotlin.dsl.extra import kotlin.streams.asStream @@ -12,28 +11,33 @@ import kotlin.streams.asStream * Configures a directory where addons will be put. */ fun Project.addonDir(dir: File, task: Task) { - task.dependsOn("compileAddons") - task.doFirst { - dir.parentFile.mkdirs() - matchingAddons(dir) { - it.name.startsWith("Terra-") // Assume everything that starts with Terra- is a core addon. - }.forEach { - println("Deleting old addon: " + it.absolutePath) - it.delete() - } - forSubProjects(":common:addons") { - val jar = tasks.named("shadowJar").get() as ShadowJar - - val boot = if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "bootstrap/" else "" - val target = File(dir, boot + jar.archiveFileName.get()) - - val base = "${jar.archiveBaseName.get()}-${version}" - - println("Copying addon ${jar.archiveFileName.get()} to ${target.absolutePath}. Base name: $base") + val moveAddons = tasks.register("moveAddons" + task.name) { + dependsOn("compileAddons") + doLast { + dir.parentFile.mkdirs() + matchingAddons(dir) { + it.name.startsWith("Terra-") // Assume everything that starts with Terra- is a core addon. + }.forEach { + println("Deleting old addon: " + it.absolutePath) + it.delete() + } + forSubProjects(":common:addons") { + val jar = tasks.named("shadowJar").get() as ShadowJar + + val boot = if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "bootstrap/" else "" + val target = File(dir, boot + jar.archiveFileName.get()) + + val base = "${jar.archiveBaseName.get()}-${version}" + + println("Copying addon ${jar.archiveFileName.get()} to ${target.absolutePath}. Base name: $base") + + jar.archiveFile.orNull?.asFile?.copyTo(target) + } + } - jar.archiveFile.orNull?.asFile?.copyTo(target) } - } + + task.dependsOn(moveAddons) } fun matchingAddons(dir: File, matcher: Predicate): Set { diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 01e403932f..f466b89ba2 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -19,10 +19,12 @@ object Versions { object Fabric { const val fabricLoader = "0.14.2" - const val fabricAPI = "0.53.4+1.18.2" - const val minecraft = "1.18.2" - const val yarn = "$minecraft+build.3" + const val fabricAPI = "0.55.1+1.19" + const val minecraft = "1.19" + const val yarn = "$minecraft+build.1" const val permissionsAPI = "0.1-SNAPSHOT" + const val mixin = "0.11.2+mixin.0.8.5" + const val loom = "0.11-SNAPSHOT" } object Bukkit { diff --git a/common/implementation/base/src/main/java/com/dfsek/terra/AbstractPlatform.java b/common/implementation/base/src/main/java/com/dfsek/terra/AbstractPlatform.java index 21ff745fe6..101ca6dcb8 100644 --- a/common/implementation/base/src/main/java/com/dfsek/terra/AbstractPlatform.java +++ b/common/implementation/base/src/main/java/com/dfsek/terra/AbstractPlatform.java @@ -19,33 +19,6 @@ import com.dfsek.tectonic.api.TypeRegistry; -import com.dfsek.terra.api.util.generic.pair.Pair; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.yaml.snakeyaml.Yaml; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UncheckedIOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - import com.dfsek.terra.addon.BootstrapAddonLoader; import com.dfsek.terra.addon.DependencySorter; import com.dfsek.terra.addon.EphemeralAddon; @@ -64,6 +37,7 @@ import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.api.registry.Registry; import com.dfsek.terra.api.registry.key.StringIdentifiable; +import com.dfsek.terra.api.util.generic.pair.Pair; import com.dfsek.terra.api.util.mutable.MutableBoolean; import com.dfsek.terra.api.util.reflection.TypeKey; import com.dfsek.terra.config.GenericLoaders; @@ -75,6 +49,21 @@ import com.dfsek.terra.registry.OpenRegistryImpl; import com.dfsek.terra.registry.master.ConfigRegistry; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; + +import java.io.*; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.stream.Collectors; + /** * Skeleton implementation of {@link Platform} @@ -119,8 +108,10 @@ protected void load() { logger.info("Initializing Terra..."); try(InputStream stream = getClass().getResourceAsStream("/config.yml")) { + logger.info("Loading config.yml"); File configFile = new File(getDataFolder(), "config.yml"); if(!configFile.exists()) { + logger.info("Writing new config.yml..."); FileUtils.copyInputStreamToFile(stream, configFile); } } catch(IOException e) { @@ -222,6 +213,7 @@ protected void dumpResources() { Path data = getDataFolder().toPath(); Path addonsPath = data.resolve("addons"); + Files.createDirectories(addonsPath); Set> paths = Files .walk(addonsPath) .map(path -> Pair.of(path, data.relativize(path).toString())) @@ -249,7 +241,6 @@ protected void dumpResources() { .collect(Collectors.toSet()); - // Terra-aaa-aaa-1.2.3-BETA+1e6af8923d.jar String resourceYaml = IOUtils.toString(resourcesConfig, StandardCharsets.UTF_8); Map> resources = new Yaml().load(resourceYaml); resources.forEach((dir, entries) -> entries.forEach(entry -> { @@ -258,42 +249,44 @@ protected void dumpResources() { if(resource.exists()) return; // dont overwrite - paths - .stream() - .filter(Pair.testRight(resourcePath::startsWith)) - .forEach(Pair.consumeLeft(path -> { - logger.info("Removing outdated resource {}, replacing with {}", path, resourcePath); - try { - Files.delete(path); - } catch(IOException e) { - throw new UncheckedIOException(e); - } - })); - - if(pathsNoMajor - .stream() - .anyMatch(resourcePath::startsWith) && // if any share name - paths - .stream() - .map(Pair.unwrapRight()) - .noneMatch(resourcePath::startsWith)) { // but dont share major version - logger.warn( - "Addon {} has a new major version available. It will not be automatically updated; you will need to ensure " + - "compatibility and update manually.", - resourcePath); - } - - logger.info("Dumping resource {}...", resource.getAbsolutePath()); - try { + try(InputStream is = getClass().getResourceAsStream("/" + resourcePath)) { + if(is == null) { + logger.error("Resource {} doesn't exist on the classpath!", resourcePath); + return; + } + + paths + .stream() + .filter(Pair.testRight(resourcePath::startsWith)) + .forEach(Pair.consumeLeft(path -> { + logger.info("Removing outdated resource {}, replacing with {}", path, resourcePath); + try { + Files.delete(path); + } catch(IOException e) { + throw new UncheckedIOException(e); + } + })); + + if(pathsNoMajor + .stream() + .anyMatch(resourcePath::startsWith) && // if any share name + paths + .stream() + .map(Pair.unwrapRight()) + .noneMatch(resourcePath::startsWith)) { // but dont share major version + logger.warn( + "Addon {} has a new major version available. It will not be automatically updated; you will need to " + + "ensure " + + "compatibility and update manually.", + resourcePath); + } + + logger.info("Dumping resource {}...", resource.getAbsolutePath()); resource.getParentFile().mkdirs(); resource.createNewFile(); - } catch(IOException e) { - throw new UncheckedIOException(e); - } - logger.debug("Copying resource {}", resourcePath); - try(InputStream is = getClass().getResourceAsStream("/" + resourcePath); - OutputStream os = new FileOutputStream(resource)) { - IOUtils.copy(is, os); + try(OutputStream os = new FileOutputStream(resource)) { + IOUtils.copy(is, os); + } } catch(IOException e) { throw new UncheckedIOException(e); } diff --git a/common/implementation/bootstrap-addon-loader/src/main/java/com/dfsek/terra/addon/BootstrapAddonLoader.java b/common/implementation/bootstrap-addon-loader/src/main/java/com/dfsek/terra/addon/BootstrapAddonLoader.java index f3b56cde71..37eba47621 100644 --- a/common/implementation/bootstrap-addon-loader/src/main/java/com/dfsek/terra/addon/BootstrapAddonLoader.java +++ b/common/implementation/bootstrap-addon-loader/src/main/java/com/dfsek/terra/addon/BootstrapAddonLoader.java @@ -74,21 +74,24 @@ private BootstrapBaseAddon loadAddon(Path addonPath, BootstrapAddonClassLoade } } catch(IOException e) { - throw new UncheckedIOException(e); + throw new AddonLoadException("Failed to load addon from path " + addonPath, e); } } @Override public Iterable> loadAddons(Path addonsFolder, BootstrapAddonClassLoader parent) { - Path bootstrapFolder = addonsFolder.resolve("bootstrap"); - logger.debug("Loading bootstrap addons from {}", bootstrapFolder); - - try(Stream bootstrapAddons = Files.walk(bootstrapFolder, 1, FileVisitOption.FOLLOW_LINKS)) { - return bootstrapAddons.filter(path -> path.toFile().isFile()) - .filter(path -> path.toFile().canRead()) - .filter(path -> path.toString().endsWith(".jar")) - .map(path -> loadAddon(path, parent)) - .collect(Collectors.toList()); + try { + Path bootstrapFolder = addonsFolder.resolve("bootstrap"); + Files.createDirectories(bootstrapFolder); + logger.debug("Loading bootstrap addons from {}", bootstrapFolder); + + try(Stream bootstrapAddons = Files.walk(bootstrapFolder, 1, FileVisitOption.FOLLOW_LINKS)) { + return bootstrapAddons.filter(path -> path.toFile().isFile()) + .filter(path -> path.toFile().canRead()) + .filter(path -> path.toString().endsWith(".jar")) + .map(path -> loadAddon(path, parent)) + .collect(Collectors.toList()); + } } catch(IOException e) { throw new UncheckedIOException(e); } diff --git a/platforms/fabric/build.gradle.kts b/platforms/fabric/build.gradle.kts index 610606dc1e..e84d533919 100644 --- a/platforms/fabric/build.gradle.kts +++ b/platforms/fabric/build.gradle.kts @@ -3,7 +3,7 @@ import com.modrinth.minotaur.TaskModrinthUpload import net.fabricmc.loom.task.RemapJarTask plugins { - id("fabric-loom").version("0.11-SNAPSHOT") + id("fabric-loom").version(Versions.Fabric.loom) id("com.modrinth.minotaur").version("1.1.0") } @@ -15,7 +15,7 @@ dependencies { modImplementation("net.fabricmc:fabric-loader:${Versions.Fabric.fabricLoader}") - setOf("fabric-command-api-v1", "fabric-lifecycle-events-v1", "fabric-resource-loader-v0", "fabric-api-base").forEach { apiModule -> + setOf("fabric-lifecycle-events-v1", "fabric-resource-loader-v0", "fabric-api-base").forEach { apiModule -> val module = fabricApi.module(apiModule, Versions.Fabric.fabricAPI) modImplementation(module) include(module) @@ -24,8 +24,12 @@ dependencies { include(modImplementation("me.lucko", "fabric-permissions-api", Versions.Fabric.permissionsAPI)) include("me.lucko", "fabric-permissions-api", Versions.Fabric.permissionsAPI) - include(modImplementation("cloud.commandframework", "cloud-fabric", Versions.Libraries.cloud)) - include("cloud.commandframework", "cloud-fabric", Versions.Libraries.cloud) + "compileOnly"("net.fabricmc:sponge-mixin:${Versions.Fabric.mixin}") + "annotationProcessor"("net.fabricmc:sponge-mixin:${Versions.Fabric.mixin}") + "annotationProcessor"("net.fabricmc:fabric-loom:${Versions.Fabric.loom}") + + //include(modImplementation("cloud.commandframework", "cloud-fabric", Versions.Libraries.cloud)) + //include("cloud.commandframework", "cloud-fabric", Versions.Libraries.cloud) } loom { diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/FabricEntryPoint.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/FabricEntryPoint.java index a6bd9b3410..7974d88845 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/FabricEntryPoint.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/FabricEntryPoint.java @@ -17,17 +17,13 @@ package com.dfsek.terra.fabric; -import cloud.commandframework.execution.CommandExecutionCoordinator; -import cloud.commandframework.fabric.FabricServerCommandManager; import net.fabricmc.api.ModInitializer; -import net.minecraft.server.command.ServerCommandSource; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; +import net.minecraft.world.gen.WorldPresets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.dfsek.terra.api.command.CommandSender; -import com.dfsek.terra.api.event.events.platform.CommandRegistrationEvent; import com.dfsek.terra.fabric.data.Codecs; @@ -49,7 +45,7 @@ public static void register() { // register the things @Override public void onInitialize() { logger.info("Initializing Terra Fabric mod..."); - + /* FabricServerCommandManager manager = new FabricServerCommandManager<>( CommandExecutionCoordinator.simpleCoordinator(), serverCommandSource -> (CommandSender) serverCommandSource, @@ -60,5 +56,7 @@ public void onInitialize() { manager.brigadierManager().setNativeNumberSuggestions(false); TERRA_PLUGIN.getEventManager().callEvent(new CommandRegistrationEvent(manager)); + TODO: re-enable when Cloud updates + */ } } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/PlatformImpl.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/PlatformImpl.java index 299465f202..fef99d2cd8 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/PlatformImpl.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/PlatformImpl.java @@ -29,7 +29,6 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.util.Identifier; import net.minecraft.util.registry.BuiltinRegistries; -import net.minecraft.world.biome.Biome.Category; import net.minecraft.world.biome.Biome.Precipitation; import net.minecraft.world.biome.BiomeEffects.GrassColorModifier; import org.jetbrains.annotations.NotNull; @@ -39,6 +38,7 @@ import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import com.dfsek.terra.AbstractPlatform; import com.dfsek.terra.addon.EphemeralAddon; @@ -68,6 +68,10 @@ public void setServer(MinecraftServer server) { this.server = server; } + public MinecraftServer getServer() { + return server; + } + @Override public boolean reload() { getTerraConfig().load(this); @@ -157,9 +161,10 @@ public void register(TypeRegistry registry) { throw new LoadException("Invalid identifier: " + o, depthTracker); return identifier; }) - .registerLoader(Precipitation.class, (type, o, loader, depthTracker) -> Precipitation.byName((String) o)) - .registerLoader(Category.class, (type, o, loader, depthTracker) -> Category.byName((String) o)) - .registerLoader(GrassColorModifier.class, (type, o, loader, depthTracker) -> GrassColorModifier.byName((String) o)); + .registerLoader(Precipitation.class, (type, o, loader, depthTracker) -> Precipitation.valueOf(((String) o).toUpperCase( + Locale.ROOT))) + .registerLoader(GrassColorModifier.class, (type, o, loader, depthTracker) -> GrassColorModifier.valueOf(((String) o).toUpperCase( + Locale.ROOT))); } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/config/PreLoadCompatibilityOptions.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/config/PreLoadCompatibilityOptions.java index 0bf7f0de10..8533ef1a0f 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/config/PreLoadCompatibilityOptions.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/config/PreLoadCompatibilityOptions.java @@ -38,6 +38,10 @@ public class PreLoadCompatibilityOptions implements ConfigTemplate, Properties { @Default private double beardThreshold = 0.5; + @Value("fabric.beard.air-threshold") + @Default + private double airThreshold = -0.5; + public boolean useVanillaBiomes() { return vanillaBiomes; } @@ -49,4 +53,8 @@ public boolean isBeard() { public double getBeardThreshold() { return beardThreshold; } + + public double getAirThreshold() { + return airThreshold; + } } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/config/VanillaBiomeProperties.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/config/VanillaBiomeProperties.java index 52dbf71628..889c9148fd 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/config/VanillaBiomeProperties.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/config/VanillaBiomeProperties.java @@ -3,7 +3,6 @@ import com.dfsek.tectonic.api.config.template.ConfigTemplate; import com.dfsek.tectonic.api.config.template.annotations.Default; import com.dfsek.tectonic.api.config.template.annotations.Value; -import net.minecraft.world.biome.Biome.Category; import net.minecraft.world.biome.Biome.Precipitation; import net.minecraft.world.biome.BiomeEffects.GrassColorModifier; @@ -43,10 +42,6 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties { @Default private Precipitation precipitation = null; - @Value("climate.category") - @Default - private Category category = null; - public Integer getFogColor() { return fogColor; } @@ -71,10 +66,6 @@ public Integer getSkyColor() { return skyColor; } - public Category getCategory() { - return category; - } - public Precipitation getPrecipitation() { return precipitation; } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/data/Codecs.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/data/Codecs.java index a1164de1e7..a2d2222c74 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/data/Codecs.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/data/Codecs.java @@ -39,32 +39,27 @@ public final class Codecs { .fieldOf("biome_registry") .stable() .forGetter(TerraBiomeSource::getBiomeRegistry), - Codec.LONG.fieldOf("seed") - .stable() - .forGetter(TerraBiomeSource::getSeed), CONFIG_PACK.fieldOf("pack") .stable() .forGetter(TerraBiomeSource::getPack)) .apply(instance, instance.stable(TerraBiomeSource::new))); - public static final Codec FABRIC_CHUNK_GENERATOR_WRAPPER = RecordCodecBuilder.create( - instance -> instance.group( - RegistryOps.createRegistryCodec(Registry.STRUCTURE_SET_KEY) - .fieldOf("structure_registry") - .stable() - .forGetter(FabricChunkGeneratorWrapper::getNoiseRegistry), - TERRA_BIOME_SOURCE.fieldOf("biome_source") - .stable() - .forGetter(FabricChunkGeneratorWrapper::getBiomeSource), - Codec.LONG.fieldOf("seed") - .stable() - .forGetter(FabricChunkGeneratorWrapper::getSeed), - CONFIG_PACK.fieldOf("pack") - .stable() - .forGetter(FabricChunkGeneratorWrapper::getPack), - ChunkGeneratorSettings.REGISTRY_CODEC.fieldOf("settings") - .stable() - .forGetter(FabricChunkGeneratorWrapper::getSettings) - ).apply(instance, instance.stable(FabricChunkGeneratorWrapper::new)) - ); + public static final Codec FABRIC_CHUNK_GENERATOR_WRAPPER = RecordCodecBuilder + .create( + instance -> instance.group( + RegistryOps.createRegistryCodec(Registry.STRUCTURE_SET_KEY) + .fieldOf("structure_registry") + .stable() + .forGetter(FabricChunkGeneratorWrapper::getNoiseRegistry), + TERRA_BIOME_SOURCE.fieldOf("biome_source") + .stable() + .forGetter(FabricChunkGeneratorWrapper::getBiomeSource), + CONFIG_PACK.fieldOf("pack") + .stable() + .forGetter(FabricChunkGeneratorWrapper::getPack), + ChunkGeneratorSettings.REGISTRY_CODEC.fieldOf("settings") + .stable() + .forGetter(FabricChunkGeneratorWrapper::getSettings) + ).apply(instance, instance.stable(FabricChunkGeneratorWrapper::new)) + ); } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/BeardGenerator.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/BeardGenerator.java deleted file mode 100644 index 114320488a..0000000000 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/BeardGenerator.java +++ /dev/null @@ -1,178 +0,0 @@ -package com.dfsek.terra.fabric.generation; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import it.unimi.dsi.fastutil.objects.ObjectList; -import it.unimi.dsi.fastutil.objects.ObjectListIterator; -import net.minecraft.block.BlockState; -import net.minecraft.structure.JigsawJunction; -import net.minecraft.structure.PoolStructurePiece; -import net.minecraft.structure.StructurePiece; -import net.minecraft.structure.StructureStart; -import net.minecraft.structure.pool.StructurePool.Projection; -import net.minecraft.util.Util; -import net.minecraft.util.math.BlockBox; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.ChunkPos; -import net.minecraft.util.math.ChunkSectionPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.gen.StructureAccessor; -import net.minecraft.world.gen.StructureWeightType; - -import com.dfsek.terra.api.world.biome.generation.BiomeProvider; -import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; -import com.dfsek.terra.api.world.info.WorldProperties; - - -// net.minecraft.world.gen.StructureWeightSampler -public class BeardGenerator { - private static final float[] STRUCTURE_WEIGHT_TABLE = Util.make(new float[13824], array -> { - for(int i = 0; i < 24; ++i) { - for(int j = 0; j < 24; ++j) { - for(int k = 0; k < 24; ++k) { - array[i * 24 * 24 + j * 24 + k] = (float) calculateStructureWeight(j - 12, k - 12, i - 12); - } - } - } - }); - private final ObjectList pieces; - private final ObjectList junctions; - private final ObjectListIterator pieceIterator; - private final ObjectListIterator junctionIterator; - private final Chunk chunk; - private final int minY; - private final int maxY; - - private final double threshold; - - public BeardGenerator(StructureAccessor structureAccessor, Chunk chunk, double threshold) { - this.chunk = chunk; - this.threshold = threshold; - ChunkPos chunkPos = chunk.getPos(); - int i = chunkPos.getStartX(); - int j = chunkPos.getStartZ(); - this.junctions = new ObjectArrayList<>(32); - this.pieces = new ObjectArrayList<>(10); - int minY = chunk.getBottomY(); - int maxY = chunk.getTopY(); - for(StructureStart start : structureAccessor.method_41035(ChunkSectionPos.from(chunk), - configuredStructureFeature -> configuredStructureFeature.field_37144)) { - for(StructurePiece structurePiece : start.getChildren()) { - if(!structurePiece.intersectsChunk(chunkPos, 12)) continue; - if(structurePiece instanceof PoolStructurePiece poolStructurePiece) { - Projection projection = poolStructurePiece.getPoolElement().getProjection(); - if(projection == Projection.RIGID) { - this.pieces.add(poolStructurePiece); - } - for(JigsawJunction jigsawJunction : poolStructurePiece.getJunctions()) { - int k = jigsawJunction.getSourceX(); - int l = jigsawJunction.getSourceZ(); - if(k <= i - 12 || l <= j - 12 || k >= i + 15 + 12 || l >= j + 15 + 12) continue; - maxY = Math.max(maxY, jigsawJunction.getSourceGroundY()); - minY = Math.min(minY, jigsawJunction.getSourceGroundY()); - this.junctions.add(jigsawJunction); - } - continue; - } - maxY = Math.max(maxY, structurePiece.getCenter().getY()); - minY = Math.min(minY, structurePiece.getCenter().getY()); - this.pieces.add(structurePiece); - } - } - this.pieceIterator = this.pieces.iterator(); - this.junctionIterator = this.junctions.iterator(); - this.minY = minY; - this.maxY = maxY; - } - - private static double getMagnitudeWeight(int x, int y, int z) { - double d = MathHelper.magnitude(x, (double) y / 2.0, z); - return MathHelper.clampedLerpFromProgress(d, 0.0, 6.0, 1.0, 0.0); - } - - /** - * Gets the structure weight from the array from the given position, or 0 if the position is out of bounds. - */ - private static double getStructureWeight(int x, int y, int z) { - int xOffset = x + 12; - int yOffset = y + 12; - int zOffset = z + 12; - if(xOffset < 0 || xOffset >= 24) { - return 0.0; - } - if(yOffset < 0 || yOffset >= 24) { - return 0.0; - } - if(zOffset < 0 || zOffset >= 24) { - return 0.0; - } - return STRUCTURE_WEIGHT_TABLE[zOffset * 24 * 24 + xOffset * 24 + yOffset]; - } - - /** - * Calculates the structure weight for the given position. - *

The weight increases as x and z approach {@code (0, 0)}, and positive y values make the weight negative while negative y - * values make the weight positive. - */ - private static double calculateStructureWeight(int x, int y, int z) { - double horizontalDistanceSquared = x * x + z * z; - double yOffset = y + 0.5; - double verticalSquared = yOffset * yOffset; - double naturalDistance = Math.pow(Math.E, -(verticalSquared / 16.0 + horizontalDistanceSquared / 16.0)); - double inverseSquareRootDistance = -yOffset * MathHelper.fastInverseSqrt(verticalSquared / 2.0 + horizontalDistanceSquared / 2.0) / - 2.0; - return inverseSquareRootDistance * naturalDistance; - } - - public void generate(ChunkGenerator generator, WorldProperties worldProperties, BiomeProvider biomeProvider) { - int xi = chunk.getPos().x << 4; - int zi = chunk.getPos().z << 4; - for(int x = 0; x < 16; x++) { - for(int z = 0; z < 16; z++) { - int depth = 0; - for(int y = maxY; y >= minY; y--) { - if(calculateNoise(x + xi, y, z + zi) > threshold) { - chunk.setBlockState(new BlockPos(x, y, z), (BlockState) generator - .getPalette(x + xi, y, z + zi, worldProperties, biomeProvider) - .get(depth, x + xi, y, z + zi, worldProperties.getSeed()), false); - depth++; - } else { - depth = 0; - } - } - } - } - } - - public double calculateNoise(int x, int y, int z) { - double noise = 0.0; - - while(this.pieceIterator.hasNext()) { - StructurePiece structurePiece = this.pieceIterator.next(); - BlockBox blockBox = structurePiece.getBoundingBox(); - int structureX = Math.max(0, Math.max(blockBox.getMinX() - x, x - blockBox.getMaxX())); - int structureY = y - (blockBox.getMinY() + (structurePiece instanceof PoolStructurePiece - ? ((PoolStructurePiece) structurePiece).getGroundLevelDelta() - : 0)); - int structureZ = Math.max(0, Math.max(blockBox.getMinZ() - z, z - blockBox.getMaxZ())); - StructureWeightType structureWeightType = structurePiece.getWeightType(); - if(structureWeightType == StructureWeightType.BURY) { - noise += getMagnitudeWeight(structureX, structureY, structureZ); - continue; - } - if(structureWeightType != StructureWeightType.BEARD) continue; - - noise += getStructureWeight(structureX, structureY, structureZ) * 0.8; - } - this.pieceIterator.back(this.pieces.size()); - while(this.junctionIterator.hasNext()) { - JigsawJunction structurePiece = this.junctionIterator.next(); - int structureX = x - structurePiece.getSourceX(); - int structureY = y - structurePiece.getSourceGroundY(); - int structureZ = z - structurePiece.getSourceZ(); - noise += getStructureWeight(structureX, structureY, structureZ) * 0.4; - } - this.junctionIterator.back(this.junctions.size()); - return noise; - } -} diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/FabricChunkGeneratorWrapper.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/FabricChunkGeneratorWrapper.java index b5f3282391..26bd28dc65 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/FabricChunkGeneratorWrapper.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/FabricChunkGeneratorWrapper.java @@ -17,32 +17,34 @@ package com.dfsek.terra.fabric.generation; -import com.dfsek.terra.api.world.info.WorldProperties; - import com.mojang.serialization.Codec; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.structure.StructureSet; +import net.minecraft.util.Util; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.random.CheckedRandom; +import net.minecraft.util.math.random.ChunkRandom; +import net.minecraft.util.math.random.RandomSeed; import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.RegistryEntry; import net.minecraft.world.ChunkRegion; import net.minecraft.world.HeightLimitView; -import net.minecraft.world.Heightmap; +import net.minecraft.world.Heightmap.Type; import net.minecraft.world.SpawnHelper; import net.minecraft.world.StructureWorldAccess; import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.source.BiomeAccess; -import net.minecraft.world.biome.source.util.MultiNoiseUtil; import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.gen.GenerationStep; +import net.minecraft.world.gen.GenerationStep.Carver; import net.minecraft.world.gen.StructureAccessor; +import net.minecraft.world.gen.StructureWeightSampler; import net.minecraft.world.gen.chunk.Blender; import net.minecraft.world.gen.chunk.ChunkGeneratorSettings; import net.minecraft.world.gen.chunk.VerticalBlockSample; -import net.minecraft.world.gen.random.AtomicSimpleRandom; -import net.minecraft.world.gen.random.ChunkRandom; -import net.minecraft.world.gen.random.RandomSeed; +import net.minecraft.world.gen.densityfunction.DensityFunction.UnblendedNoisePos; +import net.minecraft.world.gen.noise.NoiseConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,6 +60,7 @@ import com.dfsek.terra.api.world.chunk.generation.ProtoWorld; import com.dfsek.terra.api.world.chunk.generation.stage.Chunkified; import com.dfsek.terra.api.world.chunk.generation.util.GeneratorWrapper; +import com.dfsek.terra.api.world.info.WorldProperties; import com.dfsek.terra.fabric.config.PreLoadCompatibilityOptions; import com.dfsek.terra.fabric.data.Codecs; import com.dfsek.terra.fabric.mixin.access.StructureAccessorAccessor; @@ -67,16 +70,15 @@ public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.ChunkGenerator implements GeneratorWrapper { private static final Logger logger = LoggerFactory.getLogger(FabricChunkGeneratorWrapper.class); - private final long seed; private final TerraBiomeSource biomeSource; private final Registry noiseRegistry; private final RegistryEntry settings; private ChunkGenerator delegate; private ConfigPack pack; - public FabricChunkGeneratorWrapper(Registry noiseRegistry, TerraBiomeSource biomeSource, long seed, ConfigPack configPack, + public FabricChunkGeneratorWrapper(Registry noiseRegistry, TerraBiomeSource biomeSource, ConfigPack configPack, RegistryEntry settingsSupplier) { - super(noiseRegistry, Optional.empty(), biomeSource, biomeSource, seed); + super(noiseRegistry, Optional.empty(), biomeSource); this.noiseRegistry = noiseRegistry; this.pack = configPack; this.settings = settingsSupplier; @@ -84,8 +86,6 @@ public FabricChunkGeneratorWrapper(Registry noiseRegistry, TerraBi this.delegate = pack.getGeneratorProvider().newInstance(pack); logger.info("Loading world with config pack {}", pack.getID()); this.biomeSource = biomeSource; - - this.seed = seed; } public Registry getNoiseRegistry() { @@ -96,29 +96,21 @@ public Registry getNoiseRegistry() { protected Codec getCodec() { return Codecs.FABRIC_CHUNK_GENERATOR_WRAPPER; } - - @Override - public net.minecraft.world.gen.chunk.ChunkGenerator withSeed(long seed) { - return new FabricChunkGeneratorWrapper(noiseRegistry, (TerraBiomeSource) this.biomeSource.withSeed(seed), seed, pack, settings); - } - - @Override - public MultiNoiseUtil.MultiNoiseSampler getMultiNoiseSampler() { - return MultiNoiseUtil.method_40443(); // zero - } - + @Override - public void buildSurface(ChunkRegion region, StructureAccessor structures, Chunk chunk) { + public void buildSurface(ChunkRegion region, StructureAccessor structures, NoiseConfig noiseConfig, Chunk chunk) { // no op } @Override public void populateEntities(ChunkRegion region) { - ChunkPos chunkPos = region.getCenterPos(); - RegistryEntry biome = region.getBiome(chunkPos.getStartPos().withY(region.getTopY() - 1)); - ChunkRandom chunkRandom = new ChunkRandom(new AtomicSimpleRandom(RandomSeed.getSeed())); - chunkRandom.setPopulationSeed(region.getSeed(), chunkPos.getStartX(), chunkPos.getStartZ()); - SpawnHelper.populateEntities(region, biome, chunkPos, chunkRandom); + if (!this.settings.value().mobGenerationDisabled()) { + ChunkPos chunkPos = region.getCenterPos(); + RegistryEntry registryEntry = region.getBiome(chunkPos.getStartPos().withY(region.getTopY() - 1)); + ChunkRandom chunkRandom = new ChunkRandom(new CheckedRandom(RandomSeed.getSeed())); + chunkRandom.setPopulationSeed(region.getSeed(), chunkPos.getStartX(), chunkPos.getStartZ()); + SpawnHelper.populateEntities(region, registryEntry, chunkPos, chunkRandom); + } } @Override @@ -126,20 +118,49 @@ public int getWorldHeight() { return settings.value().generationShapeConfig().height(); } + + @Override - public CompletableFuture populateNoise(Executor executor, Blender arg, StructureAccessor structureAccessor, Chunk chunk) { + public CompletableFuture populateNoise(Executor executor, Blender blender, NoiseConfig noiseConfig, + StructureAccessor structureAccessor, Chunk chunk) { return CompletableFuture.supplyAsync(() -> { ProtoWorld world = (ProtoWorld) ((StructureAccessorAccessor) structureAccessor).getWorld(); BiomeProvider biomeProvider = pack.getBiomeProvider().caching(world); delegate.generateChunkData((ProtoChunk) chunk, world, biomeProvider, chunk.getPos().x, chunk.getPos().z); - + PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class); if(compatibilityOptions.isBeard()) { - new BeardGenerator(structureAccessor, chunk, compatibilityOptions.getBeardThreshold()).generate(delegate, world, - biomeProvider); + beard(structureAccessor, chunk, world, biomeProvider, compatibilityOptions); } return chunk; - }, executor); + }, Util.getMainWorkerExecutor()); + } + + private void beard(StructureAccessor structureAccessor, Chunk chunk, WorldProperties world, BiomeProvider biomeProvider, + PreLoadCompatibilityOptions compatibilityOptions) { + StructureWeightSampler structureWeightSampler = StructureWeightSampler.method_42695(structureAccessor, chunk.getPos()); + double threshold = compatibilityOptions.getBeardThreshold(); + double airThreshold = compatibilityOptions.getAirThreshold(); + int xi = chunk.getPos().x << 4; + int zi = chunk.getPos().z << 4; + for(int x = 0; x < 16; x++) { + for(int z = 0; z < 16; z++) { + int depth = 0; + for(int y = world.getMaxHeight(); y >= world.getMinHeight(); y--) { + double noise = structureWeightSampler.sample(new UnblendedNoisePos(x + xi, y, z + zi)); + if(noise > threshold) { + chunk.setBlockState(new BlockPos(x, y, z), (BlockState) delegate + .getPalette(x + xi, y, z + zi, world, biomeProvider) + .get(depth, x + xi, y, z + zi, world.getSeed()), false); + depth++; + } else if(noise < airThreshold) { + chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.getDefaultState(), false); + } else { + depth = 0; + } + } + } + } } @Override @@ -162,10 +183,11 @@ public int getMinimumY() { return settings.value().generationShapeConfig().minimumY(); } + @Override - public int getHeight(int x, int z, Heightmap.Type heightmap, HeightLimitView height) { + public int getHeight(int x, int z, Type heightmap, HeightLimitView height, NoiseConfig noiseConfig) { int y = height.getTopY(); - WorldProperties properties = FabricAdapter.adapt(height, seed); + WorldProperties properties = FabricAdapter.adapt(height, noiseConfig.getLegacyWorldSeed()); BiomeProvider biomeProvider = pack.getBiomeProvider().caching(properties); while(y >= getMinimumY() && !heightmap.getBlockPredicate().test( (BlockState) delegate.getBlock(properties, x, y - 1, z, biomeProvider))) { @@ -175,9 +197,9 @@ public int getHeight(int x, int z, Heightmap.Type heightmap, HeightLimitView hei } @Override - public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView height) { + public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView height, NoiseConfig noiseConfig) { BlockState[] array = new BlockState[height.getHeight()]; - WorldProperties properties = FabricAdapter.adapt(height, seed); + WorldProperties properties = FabricAdapter.adapt(height, noiseConfig.getLegacyWorldSeed()); BiomeProvider biomeProvider = pack.getBiomeProvider().caching(properties); for(int y = height.getTopY() - 1; y >= height.getBottomY(); y--) { array[y - height.getBottomY()] = (BlockState) delegate.getBlock(properties, x, y, z, biomeProvider); @@ -186,7 +208,7 @@ public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView height) } @Override - public void getDebugHudText(List text, BlockPos pos) { + public void getDebugHudText(List text, NoiseConfig noiseConfig, BlockPos pos) { } @@ -203,9 +225,9 @@ public void setPack(ConfigPack pack) { } @Override - public void carve(ChunkRegion chunkRegion, long seed, BiomeAccess biomeAccess, StructureAccessor structureAccessor, Chunk chunk, - GenerationStep.Carver generationStep) { - + public void carve(ChunkRegion chunkRegion, long seed, NoiseConfig noiseConfig, BiomeAccess world, StructureAccessor structureAccessor, + Chunk chunk, Carver carverStep) { + // no op } @Override @@ -213,10 +235,6 @@ public ChunkGenerator getHandle() { return delegate; } - public long getSeed() { - return seed; - } - public RegistryEntry getSettings() { return settings; } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/TerraBiomeSource.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/TerraBiomeSource.java index e90e5d46cf..17aaa343fb 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/TerraBiomeSource.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/TerraBiomeSource.java @@ -22,7 +22,11 @@ import com.dfsek.terra.fabric.data.Codecs; import com.dfsek.terra.fabric.util.ProtoPlatformBiome; +import com.dfsek.terra.fabric.util.SeedHack; + import com.mojang.serialization.Codec; +import it.unimi.dsi.fastutil.objects.Object2LongMap; +import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.RegistryEntry; import net.minecraft.world.biome.source.BiomeSource; @@ -30,6 +34,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Map; import java.util.stream.StreamSupport; @@ -37,17 +42,15 @@ public class TerraBiomeSource extends BiomeSource { private static final Logger LOGGER = LoggerFactory.getLogger(TerraBiomeSource.class); private final Registry biomeRegistry; - private final long seed; private ConfigPack pack; - public TerraBiomeSource(Registry biomes, long seed, ConfigPack pack) { + public TerraBiomeSource(Registry biomes, ConfigPack pack) { super(StreamSupport .stream(pack.getBiomeProvider() .getBiomes() .spliterator(), false) .map(b -> biomes.getOrCreateEntry(((ProtoPlatformBiome) b.getPlatformBiome()).getDelegate()))); this.biomeRegistry = biomes; - this.seed = seed; this.pack = pack; LOGGER.debug("Biomes: " + getBiomes()); @@ -58,17 +61,12 @@ protected Codec getCodec() { return Codecs.TERRA_BIOME_SOURCE; } - @Override - public BiomeSource withSeed(long seed) { - return new TerraBiomeSource(this.biomeRegistry, seed, pack); - } - @Override public RegistryEntry getBiome(int biomeX, int biomeY, int biomeZ, MultiNoiseSampler noiseSampler) { return biomeRegistry .entryOf(((ProtoPlatformBiome) pack .getBiomeProvider() - .getBiome(biomeX << 2, biomeY << 2, biomeZ << 2, seed) + .getBiome(biomeX << 2, biomeY << 2, biomeZ << 2, SeedHack.getSeed(noiseSampler)) .getPlatformBiome()).getDelegate() ); } @@ -88,8 +86,4 @@ public ConfigPack getPack() { public void setPack(ConfigPack pack) { this.pack = pack; } - - public long getSeed() { - return seed; - } } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/TerraGeneratorType.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/TerraGeneratorType.java deleted file mode 100644 index 9b2dfa40f4..0000000000 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/generation/TerraGeneratorType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Terra. - * - * Terra is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Terra is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Terra. If not, see . - */ - -package com.dfsek.terra.fabric.generation; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.world.GeneratorType; -import net.minecraft.structure.StructureSet; -import net.minecraft.util.registry.DynamicRegistryManager; -import net.minecraft.util.registry.Registry; -import net.minecraft.util.registry.RegistryEntry; -import net.minecraft.world.gen.chunk.ChunkGenerator; -import net.minecraft.world.gen.chunk.ChunkGeneratorSettings; - -import com.dfsek.terra.api.config.ConfigPack; - - -@Environment(EnvType.CLIENT) -public class TerraGeneratorType extends GeneratorType { - private final ConfigPack pack; - - public TerraGeneratorType(ConfigPack pack) { - super("terra." + pack.getID()); - this.pack = pack; - } - - @Override - protected ChunkGenerator getChunkGenerator(DynamicRegistryManager manager, long seed) { - Registry chunkGeneratorSettingsRegistry = manager.get(Registry.CHUNK_GENERATOR_SETTINGS_KEY); - RegistryEntry - settingsSupplier = chunkGeneratorSettingsRegistry.getEntry(ChunkGeneratorSettings.OVERWORLD).orElseThrow(); - Registry noiseRegistry = manager.get(Registry.STRUCTURE_SET_KEY); - return new FabricChunkGeneratorWrapper(noiseRegistry, new TerraBiomeSource(manager.get(Registry.BIOME_KEY), seed, pack), seed, pack, - settingsSupplier); - } -} diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/handle/FabricItemHandle.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/handle/FabricItemHandle.java index 6084a68acf..beb2ee7a2d 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/handle/FabricItemHandle.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/handle/FabricItemHandle.java @@ -17,8 +17,11 @@ package com.dfsek.terra.fabric.handle; +import com.dfsek.terra.fabric.FabricEntryPoint; + import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.command.CommandRegistryAccess; import net.minecraft.command.argument.ItemStackArgumentType; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; @@ -36,7 +39,7 @@ public class FabricItemHandle implements ItemHandle { @Override public Item createItem(String data) { try { - return (Item) new ItemStackArgumentType().parse(new StringReader(data)).getItem(); + return (Item) new ItemStackArgumentType(new CommandRegistryAccess(FabricEntryPoint.getPlatform().getServer().getRegistryManager())).parse(new StringReader(data)).getItem(); } catch(CommandSyntaxException e) { throw new IllegalArgumentException("Invalid item data \"" + data + "\"", e); } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/handle/FabricWorldHandle.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/handle/FabricWorldHandle.java index 50b0083e57..ac7a0e2489 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/handle/FabricWorldHandle.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/handle/FabricWorldHandle.java @@ -17,11 +17,14 @@ package com.dfsek.terra.fabric.handle; +import com.dfsek.terra.fabric.FabricEntryPoint; + import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.block.Blocks; import net.minecraft.command.argument.BlockArgumentParser; import net.minecraft.util.Identifier; +import net.minecraft.util.registry.BuiltinRegistries; import net.minecraft.util.registry.Registry; import org.jetbrains.annotations.NotNull; @@ -36,9 +39,8 @@ public class FabricWorldHandle implements WorldHandle { @Override public @NotNull BlockState createBlockState(@NotNull String data) { - BlockArgumentParser parser = new BlockArgumentParser(new StringReader(data), true); try { - net.minecraft.block.BlockState state = parser.parse(true).getBlockState(); + net.minecraft.block.BlockState state = BlockArgumentParser.block(Registry.BLOCK, data, true).blockState(); if(state == null) throw new IllegalArgumentException("Invalid data: " + data); return (BlockState) state; } catch(CommandSyntaxException e) { diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/ReloadCommandMixin.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/ReloadCommandMixin.java new file mode 100644 index 0000000000..9fcfaae15d --- /dev/null +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/ReloadCommandMixin.java @@ -0,0 +1,25 @@ +package com.dfsek.terra.fabric.mixin; + +import com.dfsek.terra.fabric.FabricEntryPoint; + +import net.minecraft.server.command.ReloadCommand; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.text.Text; +import org.checkerframework.checker.units.qual.A; +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; + +import java.util.Collection; + + +@Mixin(ReloadCommand.class) +public class ReloadCommandMixin { + @Inject(method = "tryReloadDataPacks", at = @At("HEAD")) + private static void inject(Collection dataPacks, ServerCommandSource source, CallbackInfo ci) { + source.sendFeedback(Text.literal("Reloading Terra..."), true); + FabricEntryPoint.getPlatform().reload(); + source.sendFeedback(Text.literal("Done."), true); + } +} diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/access/GeneratorTypeAccessor.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/access/GeneratorTypeAccessor.java deleted file mode 100644 index 0b218a0ede..0000000000 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/access/GeneratorTypeAccessor.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of Terra. - * - * Terra is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Terra is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Terra. If not, see . - */ - -package com.dfsek.terra.fabric.mixin.access; - -import net.minecraft.client.world.GeneratorType; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.util.List; - - -@Mixin(GeneratorType.class) -public interface GeneratorTypeAccessor { - @Accessor("VALUES") - static List getValues() { - throw new UnsupportedOperationException(); - } - - @Mutable - @Accessor("displayName") - void setDisplayName(Text translationKey); -} diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/block/entity/SignBlockEntityMixin.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/block/entity/SignBlockEntityMixin.java index 41bdc67c3c..6757481359 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/block/entity/SignBlockEntityMixin.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/block/entity/SignBlockEntityMixin.java @@ -18,7 +18,6 @@ package com.dfsek.terra.fabric.mixin.implementations.block.entity; import net.minecraft.block.entity.SignBlockEntity; -import net.minecraft.text.LiteralText; import net.minecraft.text.Text; import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Final; @@ -42,19 +41,19 @@ public abstract class SignBlockEntityMixin { public abstract void setTextOnRow(int row, Text text); public void terra$setLine(int index, @NotNull String line) throws IndexOutOfBoundsException { - setTextOnRow(index, new LiteralText(line)); + setTextOnRow(index, Text.literal(line)); } public @NotNull String[] terra$getLines() { String[] lines = new String[texts.length]; for(int i = 0; i < texts.length; i++) { - lines[i] = texts[i].asString(); + lines[i] = texts[i].getString(); } return lines; } public @NotNull String terra$getLine(int index) throws IndexOutOfBoundsException { - return texts[index].asString(); + return texts[index].getString(); } public void terra$applyState(String state) { diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/entity/EntityMixin.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/entity/EntityMixin.java index 7a59632f99..42b006cb17 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/entity/EntityMixin.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/entity/EntityMixin.java @@ -44,9 +44,6 @@ public abstract class EntityMixin { @Shadow public abstract void teleport(double destX, double destY, double destZ); - @Shadow - public abstract void sendSystemMessage(Text message, UUID senderUuid); - public Vector3 terra$position() { return FabricAdapter.adapt(blockPos); } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/entity/ServerCommandSourceMixin.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/entity/ServerCommandSourceMixin.java index 3f6e16d1f9..23cf991c0e 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/entity/ServerCommandSourceMixin.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/entity/ServerCommandSourceMixin.java @@ -20,7 +20,6 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.LiteralText; import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Implements; @@ -49,7 +48,7 @@ public abstract class ServerCommandSourceMixin { public abstract net.minecraft.entity.@Nullable Entity getEntity(); public void terra$sendMessage(String message) { - sendFeedback(new LiteralText(message), true); + sendFeedback(Text.literal(message), true); } @Nullable diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/world/ChunkRegionMixin.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/world/ChunkRegionMixin.java index 796d2c4240..ab00eedd38 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/world/ChunkRegionMixin.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/world/ChunkRegionMixin.java @@ -81,10 +81,8 @@ public void injectConstructor(net.minecraft.server.world.ServerWorld world, List this.config = ((ServerWorld) world).getPack(); } - @SuppressWarnings("deprecation") public Entity terraWorld$spawnEntity(Vector3 location, EntityType entityType) { - net.minecraft.entity.Entity entity = ((net.minecraft.entity.EntityType) entityType).create( - ((ChunkRegion) (Object) this).toServerWorld()); + net.minecraft.entity.Entity entity = ((net.minecraft.entity.EntityType) entityType).create(null); entity.setPos(location.getX(), location.getY(), location.getZ()); ((ChunkRegion) (Object) this).spawnEntity(entity); return (Entity) entity; diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/world/ServerWorldMixin.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/world/ServerWorldMixin.java index 4273446f65..6e1c97f9ec 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/world/ServerWorldMixin.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/world/ServerWorldMixin.java @@ -42,8 +42,7 @@ @Implements(@Interface(iface = ServerWorld.class, prefix = "terra$")) public abstract class ServerWorldMixin { public Entity terra$spawnEntity(double x, double y, double z, EntityType entityType) { - net.minecraft.entity.Entity entity = ((net.minecraft.entity.EntityType) entityType).create( - ((net.minecraft.server.world.ServerWorld) (Object) this)); + net.minecraft.entity.Entity entity = ((net.minecraft.entity.EntityType) entityType).create(null); entity.setPos(x, y, z); ((net.minecraft.server.world.ServerWorld) (Object) this).spawnEntity(entity); return (Entity) entity; diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/DataPackContentsMixin.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/DataPackContentsMixin.java index fc45975973..f2e38a11d6 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/DataPackContentsMixin.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/DataPackContentsMixin.java @@ -19,8 +19,10 @@ public class DataPackContentsMixin { */ @Inject(method = "refresh(Lnet/minecraft/util/registry/DynamicRegistryManager;)V", at = @At("RETURN")) private void injectReload(DynamicRegistryManager dynamicRegistryManager, CallbackInfo ci) { + TagUtil.registerWorldPresetTags(dynamicRegistryManager.get(Registry.WORLD_PRESET_KEY)); + Registry biomeRegistry = dynamicRegistryManager.get(Registry.BIOME_KEY); - TagUtil.registerTags(biomeRegistry); + TagUtil.registerBiomeTags(biomeRegistry); BiomeUtil.registerFlora(biomeRegistry); } } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/MinecraftServerMixin.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/MinecraftServerMixin.java index 66f03a7c5a..2a545ebf06 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/MinecraftServerMixin.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/MinecraftServerMixin.java @@ -7,6 +7,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.SaveLoader; import net.minecraft.server.WorldGenerationProgressListenerFactory; +import net.minecraft.util.ApiServices; import net.minecraft.util.UserCache; import net.minecraft.world.level.storage.LevelStorage; import org.spongepowered.asm.mixin.Mixin; @@ -23,13 +24,11 @@ public class MinecraftServerMixin { @Inject(method = "(Ljava/lang/Thread;Lnet/minecraft/world/level/storage/LevelStorage$Session;" + "Lnet/minecraft/resource/ResourcePackManager;Lnet/minecraft/server/SaveLoader;Ljava/net/Proxy;" + - "Lcom/mojang/datafixers/DataFixer;Lcom/mojang/authlib/minecraft/MinecraftSessionService;" + - "Lcom/mojang/authlib/GameProfileRepository;Lnet/minecraft/util/UserCache;" + + "Lcom/mojang/datafixers/DataFixer;Lnet/minecraft/util/ApiServices;" + "Lnet/minecraft/server/WorldGenerationProgressListenerFactory;)V", at = @At("RETURN")) private void injectConstructor(Thread serverThread, LevelStorage.Session session, ResourcePackManager dataPackManager, - SaveLoader saveLoader, Proxy proxy, DataFixer dataFixer, MinecraftSessionService sessionService, - GameProfileRepository gameProfileRepo, UserCache userCache, + SaveLoader saveLoader, Proxy proxy, DataFixer dataFixer, ApiServices apiServices, WorldGenerationProgressListenerFactory worldGenerationProgressListenerFactory, CallbackInfo ci) { FabricEntryPoint.getPlatform().setServer((MinecraftServer) (Object) this); } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/NoiseConfigMixin.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/NoiseConfigMixin.java new file mode 100644 index 0000000000..6f9af2ed8e --- /dev/null +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/NoiseConfigMixin.java @@ -0,0 +1,32 @@ +package com.dfsek.terra.fabric.mixin.lifecycle; + +import com.dfsek.terra.fabric.util.SeedHack; + +import net.minecraft.util.math.noise.DoublePerlinNoiseSampler; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.biome.source.util.MultiNoiseUtil; +import net.minecraft.world.biome.source.util.MultiNoiseUtil.MultiNoiseSampler; +import net.minecraft.world.gen.chunk.ChunkGeneratorSettings; +import net.minecraft.world.gen.noise.NoiseConfig; +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; + + +/** + * Hack to map noise sampler to seeds + */ +@Mixin(NoiseConfig.class) +public class NoiseConfigMixin { + @Shadow + @Final + private MultiNoiseSampler multiNoiseSampler; + + @Inject(method = "(Lnet/minecraft/world/gen/chunk/ChunkGeneratorSettings;Lnet/minecraft/util/registry/Registry;J)V", at = @At("TAIL")) + private void mapMultiNoise(ChunkGeneratorSettings chunkGeneratorSettings, Registry noiseRegistry, long seed, CallbackInfo ci) { + SeedHack.register(multiNoiseSampler, seed); + } +} diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/client/MinecraftClientMixin.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/client/MinecraftClientMixin.java index e6ecb2626d..620ebf100c 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/client/MinecraftClientMixin.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/client/MinecraftClientMixin.java @@ -17,11 +17,10 @@ package com.dfsek.terra.fabric.mixin.lifecycle.client; -import com.dfsek.terra.fabric.util.BiomeUtil; +import com.dfsek.terra.fabric.util.LifecycleUtil; + import net.minecraft.client.MinecraftClient; import net.minecraft.client.RunArgs; -import net.minecraft.client.world.GeneratorType; -import net.minecraft.text.LiteralText; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -29,8 +28,7 @@ import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent; import com.dfsek.terra.fabric.FabricEntryPoint; -import com.dfsek.terra.fabric.generation.TerraGeneratorType; -import com.dfsek.terra.fabric.mixin.access.GeneratorTypeAccessor; +import com.dfsek.terra.fabric.util.BiomeUtil; @Mixin(MinecraftClient.class) @@ -42,13 +40,6 @@ public class MinecraftClientMixin { // sorta arbitrary position, after mod init, before window opens shift = At.Shift.BEFORE)) public void injectConstructor(RunArgs args, CallbackInfo callbackInfo) { - FabricEntryPoint.getPlatform().getEventManager().callEvent(new PlatformInitializationEvent()); - FabricEntryPoint.getPlatform().getConfigRegistry().forEach(pack -> { - final GeneratorType generatorType = new TerraGeneratorType(pack); - //noinspection ConstantConditions - ((GeneratorTypeAccessor) generatorType).setDisplayName(new LiteralText("Terra:" + pack.getID())); - GeneratorTypeAccessor.getValues().add(1, generatorType); - }); - BiomeUtil.registerBiomes(); + LifecycleUtil.initialize(); } } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/server/GeneratorOptionsMixin.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/server/GeneratorOptionsMixin.java deleted file mode 100644 index ef2a587f58..0000000000 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/server/GeneratorOptionsMixin.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * This file is part of Terra. - * - * Terra is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Terra is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Terra. If not, see . - */ - -package com.dfsek.terra.fabric.mixin.lifecycle.server; - -import net.minecraft.server.dedicated.ServerPropertiesHandler; -import net.minecraft.structure.StructureSet; -import net.minecraft.util.registry.DynamicRegistryManager; -import net.minecraft.util.registry.Registry; -import net.minecraft.util.registry.RegistryEntry; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.dimension.DimensionOptions; -import net.minecraft.world.dimension.DimensionType; -import net.minecraft.world.gen.GeneratorOptions; -import net.minecraft.world.gen.chunk.ChunkGeneratorSettings; -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.CallbackInfoReturnable; - -import java.util.Locale; -import java.util.Random; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.api.registry.CheckedRegistry; -import com.dfsek.terra.fabric.FabricEntryPoint; -import com.dfsek.terra.fabric.PlatformImpl; -import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper; -import com.dfsek.terra.fabric.generation.TerraBiomeSource; - - -@Mixin(GeneratorOptions.class) -public abstract class GeneratorOptionsMixin { - @Inject(method = "fromProperties(Lnet/minecraft/util/registry/DynamicRegistryManager;" + - "Lnet/minecraft/server/dedicated/ServerPropertiesHandler$WorldGenProperties;)" + - "Lnet/minecraft/world/gen/GeneratorOptions;", - at = @At("HEAD"), - cancellable = true) - private static void fromProperties(DynamicRegistryManager manager, - ServerPropertiesHandler.WorldGenProperties properties, - CallbackInfoReturnable cir) { - if(properties.levelType() == null) { - return; - } - - PlatformImpl main = FabricEntryPoint.getPlatform(); - - String levelType = properties.levelType(); - - if(levelType.toLowerCase(Locale.ROOT).startsWith("terra")) { - String seedProperty = properties.levelSeed(); - long seed = new Random().nextLong(); - if(seedProperty != null) { - try { - long m = Long.parseLong(seedProperty); - if(m != 0L) { - seed = m; - } - } catch(NumberFormatException exception) { - seed = seedProperty.hashCode(); - } - } - - boolean generateStructures = properties.generateStructures(); - Registry dimensionTypes = manager.get(Registry.DIMENSION_TYPE_KEY); - Registry biomeRegistry = manager.get(Registry.BIOME_KEY); - Registry dimensionOptions = DimensionType.createDefaultDimensionOptions(manager, seed, false); - - Registry chunkGeneratorSettingsRegistry = manager.get(Registry.CHUNK_GENERATOR_SETTINGS_KEY); - RegistryEntry - settingsSupplier = chunkGeneratorSettingsRegistry.getEntry(ChunkGeneratorSettings.OVERWORLD).orElseThrow(); - Registry noiseRegistry = manager.get(Registry.STRUCTURE_SET_KEY); - - String pack = levelType.substring(levelType.indexOf(":") + 1); - - CheckedRegistry configRegistry = main.getConfigRegistry(); - ConfigPack config = configRegistry - .getByID(pack) - .or(() -> configRegistry.getByID(pack.toUpperCase(Locale.ROOT))) - .orElseThrow(() -> new IllegalArgumentException("No such pack " + pack)); - - cir.setReturnValue( - new GeneratorOptions(seed, - generateStructures, - false, - GeneratorOptions - .getRegistryWithReplacedOverworldGenerator( - dimensionTypes, - dimensionOptions, - new FabricChunkGeneratorWrapper(noiseRegistry, - new TerraBiomeSource(biomeRegistry, seed, config), - seed, - config, - settingsSupplier)))); - } - } -} diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/server/ServerMainMixin.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/server/ServerMainMixin.java index 6bd8e2272e..ecf5e933b9 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/server/ServerMainMixin.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/lifecycle/server/ServerMainMixin.java @@ -18,6 +18,8 @@ package com.dfsek.terra.fabric.mixin.lifecycle.server; import com.dfsek.terra.fabric.util.BiomeUtil; +import com.dfsek.terra.fabric.util.LifecycleUtil; + import net.minecraft.server.Main; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -37,9 +39,6 @@ public class ServerMainMixin { // after registry manager creation ) private static void injectConstructor(String[] args, CallbackInfo ci) { - FabricEntryPoint.getPlatform().getEventManager().callEvent( - new PlatformInitializationEvent()); // Load during MinecraftServer construction, after other mods have registered blocks - // and stuff - BiomeUtil.registerBiomes(); + LifecycleUtil.initialize(); } } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/util/BiomeUtil.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/util/BiomeUtil.java index b02f0b08bb..d1d2ec9a9d 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/util/BiomeUtil.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/util/BiomeUtil.java @@ -137,12 +137,9 @@ public static net.minecraft.world.biome.Biome createBiome(Biome biome, net.minec effects.foliageColor(vanillaBiomeProperties.getFoliageColor()); } - - builder.precipitation(Objects.requireNonNullElse(vanillaBiomeProperties.getPrecipitation(), vanilla.getPrecipitation())) - .category(Objects.requireNonNullElse(vanillaBiomeProperties.getCategory(), vanilla.getCategory())); + builder.precipitation(Objects.requireNonNullElse(vanillaBiomeProperties.getPrecipitation(), vanilla.getPrecipitation())); } else { - effects.waterColor(vanilla.getWaterColor()) .waterFogColor(vanilla.getWaterFogColor()) .fogColor(vanilla.getFogColor()) @@ -150,11 +147,9 @@ public static net.minecraft.world.biome.Biome createBiome(Biome biome, net.minec vanilla.getEffects().getFoliageColor().ifPresent(effects::foliageColor); vanilla.getEffects().getGrassColor().ifPresent(effects::grassColor); - builder.precipitation(vanilla.getPrecipitation()) - .category(vanilla.getCategory()); + builder.precipitation(vanilla.getPrecipitation()); } - - + return builder .temperature(vanilla.getTemperature()) .downfall(vanilla.getDownfall()) diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/util/LifecycleUtil.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/util/LifecycleUtil.java new file mode 100644 index 0000000000..2e935d8898 --- /dev/null +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/util/LifecycleUtil.java @@ -0,0 +1,100 @@ +package com.dfsek.terra.fabric.util; + +import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent; +import com.dfsek.terra.fabric.FabricEntryPoint; +import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper; +import com.dfsek.terra.fabric.generation.TerraBiomeSource; + +import net.minecraft.structure.StructureSet; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.noise.DoublePerlinNoiseSampler.NoiseParameters; +import net.minecraft.util.registry.BuiltinRegistries; +import net.minecraft.util.registry.Registry; +import net.minecraft.util.registry.RegistryEntry; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.source.MultiNoiseBiomeSource; +import net.minecraft.world.biome.source.TheEndBiomeSource; +import net.minecraft.world.dimension.DimensionOptions; +import net.minecraft.world.dimension.DimensionType; +import net.minecraft.world.dimension.DimensionTypes; +import net.minecraft.world.gen.WorldPreset; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import net.minecraft.world.gen.chunk.ChunkGeneratorSettings; +import net.minecraft.world.gen.chunk.NoiseChunkGenerator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; + + +public class LifecycleUtil { + private static final Logger LOGGER = LoggerFactory.getLogger(LifecycleUtil.class); + + private static final List PRESETS = new ArrayList<>(); + public static void initialize() { + FabricEntryPoint.getPlatform().getEventManager().callEvent( + new PlatformInitializationEvent()); + BiomeUtil.registerBiomes(); + + + LOGGER.info("Registering Terra world types..."); + + Registry dimensionTypeRegistry = BuiltinRegistries.DIMENSION_TYPE; + Registry chunkGeneratorSettingsRegistry = BuiltinRegistries.CHUNK_GENERATOR_SETTINGS; + Registry structureSetRegistry = BuiltinRegistries.STRUCTURE_SET; + Registry noiseParametersRegistry = BuiltinRegistries.NOISE_PARAMETERS; + Registry biomeRegistry = BuiltinRegistries.BIOME; + + RegistryEntry theNetherDimensionType = dimensionTypeRegistry.getOrCreateEntry(DimensionTypes.THE_NETHER); + RegistryEntry + netherChunkGeneratorSettings = chunkGeneratorSettingsRegistry.getOrCreateEntry(ChunkGeneratorSettings.NETHER); + DimensionOptions netherDimensionOptions = new DimensionOptions(theNetherDimensionType, + new NoiseChunkGenerator(structureSetRegistry, + noiseParametersRegistry, + MultiNoiseBiomeSource.Preset.NETHER.getBiomeSource( + biomeRegistry), + netherChunkGeneratorSettings)); + RegistryEntry theEndDimensionType = dimensionTypeRegistry.getOrCreateEntry(DimensionTypes.THE_END); + RegistryEntry endChunkGeneratorSettings = chunkGeneratorSettingsRegistry.getOrCreateEntry( + ChunkGeneratorSettings.END); + DimensionOptions endDimensionOptions = new DimensionOptions(theEndDimensionType, + new NoiseChunkGenerator(structureSetRegistry, noiseParametersRegistry, + new TheEndBiomeSource(biomeRegistry), + endChunkGeneratorSettings)); + + RegistryEntry overworldDimensionType = dimensionTypeRegistry.getOrCreateEntry(DimensionTypes.OVERWORLD); + + RegistryEntry overworld = chunkGeneratorSettingsRegistry.getOrCreateEntry(ChunkGeneratorSettings.OVERWORLD); + FabricEntryPoint + .getPlatform() + .getRawConfigRegistry() + .forEach((id, pack) -> { + Identifier generatorID = Identifier.of("terra", pack.getID().toLowerCase(Locale.ROOT) + "/" + pack.getNamespace().toLowerCase( + Locale.ROOT)); + + PRESETS.add(generatorID); + + TerraBiomeSource biomeSource = new TerraBiomeSource(biomeRegistry, pack); + ChunkGenerator generator = new FabricChunkGeneratorWrapper(structureSetRegistry, biomeSource, pack, overworld); + + DimensionOptions dimensionOptions = new DimensionOptions(overworldDimensionType, generator); + WorldPreset preset = new WorldPreset( + Map.of( + DimensionOptions.OVERWORLD, dimensionOptions, + DimensionOptions.NETHER, netherDimensionOptions, + DimensionOptions.END, endDimensionOptions + ) + ); + BuiltinRegistries.add(BuiltinRegistries.WORLD_PRESET, generatorID, preset); + LOGGER.info("Registered world type \"{}\"", generatorID); + } + ); + } + + public static List getPresets() { + return PRESETS; + } +} diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/util/SeedHack.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/util/SeedHack.java new file mode 100644 index 0000000000..f0c59fc001 --- /dev/null +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/util/SeedHack.java @@ -0,0 +1,29 @@ +package com.dfsek.terra.fabric.util; + +import it.unimi.dsi.fastutil.objects.Object2LongMap; +import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; +import net.minecraft.world.biome.source.util.MultiNoiseUtil.MultiNoiseSampler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Holder for hacky biome source seed workaround + */ +public class SeedHack { + private static final Logger LOGGER = LoggerFactory.getLogger(SeedHack.class); + + private static final Object2LongMap seedMap = new Object2LongOpenHashMap<>(); + + public static long getSeed(MultiNoiseSampler sampler) { + if(!seedMap.containsKey(sampler)) { + throw new IllegalArgumentException("Sampler is not registered: " + sampler); + } + return seedMap.getLong(sampler); + } + + public static void register(MultiNoiseSampler sampler, long seed) { + LOGGER.info("Registered seed {} to sampler {}", seed, sampler.hashCode()); + seedMap.put(sampler, seed); + } +} diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/util/TagUtil.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/util/TagUtil.java index e39194234d..7a52ff3764 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/util/TagUtil.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/util/TagUtil.java @@ -2,9 +2,11 @@ import com.google.common.collect.ImmutableMap; import net.minecraft.tag.TagKey; +import net.minecraft.tag.WorldPresetTags; import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.RegistryEntry; import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.WorldPreset; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,48 +23,72 @@ private TagUtil() { } - public static void registerTags(Registry registry) { - logger.info("Doing tag garbage...."); - Map, List>> collect = registry + private static Map, List>> tagsToMutableMap(Registry registry) { + return registry .streamTagsAndEntries() .collect(HashMap::new, (map, pair) -> map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())), HashMap::putAll); + } + + public static void registerWorldPresetTags(Registry registry) { + logger.info("Doing preset tag garbage...."); + Map, List>> collect = tagsToMutableMap(registry); + + LifecycleUtil + .getPresets() + .forEach(id -> FabricUtil + .getEntry(registry, id) + .ifPresentOrElse( + preset -> collect + .computeIfAbsent(WorldPresetTags.NORMAL, tag -> new ArrayList<>()) + .add(preset), + () -> logger.error("Preset {} does not exist!", id))); + + registry.clearTags(); + registry.populateTags(ImmutableMap.copyOf(collect)); + } + + public static void registerBiomeTags(Registry registry) { + logger.info("Doing biome tag garbage...."); + Map, List>> collect = tagsToMutableMap(registry); BiomeUtil .getTerraBiomeMap() .forEach((vb, terraBiomes) -> - FabricUtil.getEntry(registry, vb) - .ifPresentOrElse(vanilla -> terraBiomes - .forEach(tb -> FabricUtil - .getEntry(registry, tb) - .ifPresentOrElse( - terra -> { - logger.debug( - vanilla.getKey() - .orElseThrow() - .getValue() + - " (vanilla for " + - terra.getKey() - .orElseThrow() - .getValue() + - ": " + - vanilla.streamTags() - .toList()); - - vanilla.streamTags() - .forEach( - tag -> collect - .computeIfAbsent( - tag, - t -> new ArrayList<>()) - .add(terra)); - }, - () -> logger.error( - "No such biome: {}", - tb))), - () -> logger.error("No vanilla biome: {}", vb))); + FabricUtil + .getEntry(registry, vb) + .ifPresentOrElse( + vanilla -> terraBiomes + .forEach(tb -> FabricUtil + .getEntry(registry, tb) + .ifPresentOrElse( + terra -> { + logger.debug( + vanilla.getKey() + .orElseThrow() + .getValue() + + " (vanilla for " + + terra.getKey() + .orElseThrow() + .getValue() + + ": " + + vanilla.streamTags() + .toList()); + + vanilla.streamTags() + .forEach( + tag -> collect + .computeIfAbsent( + tag, + t -> new ArrayList<>()) + .add(terra)); + }, + () -> logger.error( + "No such biome: {}", + tb))), + () -> logger.error("No vanilla biome: {}", vb))); registry.clearTags(); registry.populateTags(ImmutableMap.copyOf(collect)); diff --git a/platforms/fabric/src/main/resources/fabric.mod.json b/platforms/fabric/src/main/resources/fabric.mod.json index 9216ece307..dcc2779549 100644 --- a/platforms/fabric/src/main/resources/fabric.mod.json +++ b/platforms/fabric/src/main/resources/fabric.mod.json @@ -26,7 +26,7 @@ "depends": { "fabricloader": ">=0.14.2", "java": ">=17", - "minecraft": "1.18.x" + "minecraft": "1.19.x" }, "accessWidener": "terra.accesswidener" } \ No newline at end of file diff --git a/platforms/fabric/src/main/resources/terra.accesswidener b/platforms/fabric/src/main/resources/terra.accesswidener index 0e84c041c9..3fde5170fe 100644 --- a/platforms/fabric/src/main/resources/terra.accesswidener +++ b/platforms/fabric/src/main/resources/terra.accesswidener @@ -1,5 +1 @@ accessWidener v1 named - -extendable method net/minecraft/client/world/GeneratorType (Ljava/lang/String;)V - -accessible method net/minecraft/world/biome/Biome getCategory ()Lnet/minecraft/world/biome/Biome$Category; diff --git a/platforms/fabric/src/main/resources/terra.mixins.json b/platforms/fabric/src/main/resources/terra.mixins.json index 1a638ef5f9..778f068890 100644 --- a/platforms/fabric/src/main/resources/terra.mixins.json +++ b/platforms/fabric/src/main/resources/terra.mixins.json @@ -1,51 +1,51 @@ { - "required": true, - "minVersion": "0.8", - "package": "com.dfsek.terra.fabric.mixin", - "compatibilityLevel": "JAVA_17", - "mixins": [ - "access.MobSpawnerLogicAccessor", - "access.StateAccessor", - "access.StructureAccessorAccessor", - "compat.GenerationSettingsFloraFeaturesMixin", - "implementations.BiomeMixin", - "implementations.HandleImplementationMixin", - "implementations.block.BlockMixin", - "implementations.block.entity.BlockEntityMixin", - "implementations.block.entity.LootableContainerBlockEntityMixin", - "implementations.block.entity.MobSpawnerBlockEntityMixin", - "implementations.block.entity.SignBlockEntityMixin", - "implementations.block.state.BlockStateMixin", - "implementations.block.state.PropertyMixin", - "implementations.chunk.ChunkRegionMixin", - "implementations.chunk.WorldChunkMixin", - "implementations.chunk.data.ProtoChunkMixin", - "implementations.entity.EntityMixin", - "implementations.entity.EntityTypeMixin", - "implementations.entity.PlayerEntityMixin", - "implementations.entity.ServerCommandSourceMixin", - "implementations.inventory.LockableContainerBlockEntityMixin", - "implementations.inventory.item.ItemMixin", - "implementations.inventory.item.ItemStackMixin", - "implementations.inventory.meta.EnchantmentMixin", - "implementations.inventory.meta.ItemStackDamageableMixin", - "implementations.inventory.meta.ItemStackMetaMixin", - "implementations.world.ChunkRegionMixin", - "implementations.world.ServerWorldMixin", - "lifecycle.DataPackContentsMixin", - "lifecycle.MinecraftServerMixin", - "lifecycle.RegistryMixin" - ], - "client": [ - "access.GeneratorTypeAccessor", - "lifecycle.client.MinecraftClientMixin" - ], - "server": [ - "lifecycle.server.GeneratorOptionsMixin", - "lifecycle.server.ServerMainMixin" - ], - "injectors": { - "defaultRequire": 1 - }, - "refmap": "terra-refmap.json" + "required": true, + "minVersion": "0.8", + "package": "com.dfsek.terra.fabric.mixin", + "compatibilityLevel": "JAVA_17", + "mixins": [ + "ReloadCommandMixin", + "access.MobSpawnerLogicAccessor", + "access.StateAccessor", + "access.StructureAccessorAccessor", + "compat.GenerationSettingsFloraFeaturesMixin", + "implementations.BiomeMixin", + "implementations.HandleImplementationMixin", + "implementations.block.BlockMixin", + "implementations.block.entity.BlockEntityMixin", + "implementations.block.entity.LootableContainerBlockEntityMixin", + "implementations.block.entity.MobSpawnerBlockEntityMixin", + "implementations.block.entity.SignBlockEntityMixin", + "implementations.block.state.BlockStateMixin", + "implementations.block.state.PropertyMixin", + "implementations.chunk.ChunkRegionMixin", + "implementations.chunk.WorldChunkMixin", + "implementations.chunk.data.ProtoChunkMixin", + "implementations.entity.EntityMixin", + "implementations.entity.EntityTypeMixin", + "implementations.entity.PlayerEntityMixin", + "implementations.entity.ServerCommandSourceMixin", + "implementations.inventory.LockableContainerBlockEntityMixin", + "implementations.inventory.item.ItemMixin", + "implementations.inventory.item.ItemStackMixin", + "implementations.inventory.meta.EnchantmentMixin", + "implementations.inventory.meta.ItemStackDamageableMixin", + "implementations.inventory.meta.ItemStackMetaMixin", + "implementations.world.ChunkRegionMixin", + "implementations.world.ServerWorldMixin", + "lifecycle.DataPackContentsMixin", + "lifecycle.MinecraftServerMixin", + "lifecycle.NoiseConfigMixin", + "lifecycle.RegistryMixin" + ], + "client": [ + "lifecycle.client.MinecraftClientMixin" + ], + "server": [ + "lifecycle.server.ServerMainMixin" + ], + "injectors": { + "defaultRequire": 1 + }, + "refmap": "terra-refmap.json" } \ No newline at end of file