mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-01 23:47:50 +00:00
Merge branch 'dev/7.0-2' into dev/layered-generator
This commit is contained in:
commit
e079cdfcc0
8
.github/workflows/gradle-build.yml
vendored
8
.github/workflows/gradle-build.yml
vendored
@ -17,16 +17,16 @@ jobs:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
- uses: actions/checkout@v4.2.2
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
|
||||
uses: actions/setup-java@v4.7.1
|
||||
with:
|
||||
java-version: '21'
|
||||
distribution: 'temurin'
|
||||
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
|
||||
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
||||
|
||||
- uses: burrunan/gradle-cache-action@03c71a8ba93d670980695505f48f49daf43704a6
|
||||
- uses: burrunan/gradle-cache-action@v3.0.1
|
||||
name: Build Terra
|
||||
with:
|
||||
# Specifies arguments for Gradle execution
|
||||
@ -44,4 +44,4 @@ jobs:
|
||||
# Properties are passed as -Pname=value
|
||||
properties: |
|
||||
kotlin.js.compiler=ir
|
||||
kotlin.parallel.tasks.in.project=true
|
||||
kotlin.parallel.tasks.in.project=true
|
||||
|
@ -16,11 +16,11 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
//TODO Allow pulling from Versions.kt
|
||||
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.1")
|
||||
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.6")
|
||||
|
||||
implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "2.0.0-beta.16")
|
||||
implementation("org.ow2.asm", "asm", "9.7")
|
||||
implementation("org.ow2.asm", "asm-tree", "9.7")
|
||||
implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "2.0.0-beta.17")
|
||||
implementation("org.ow2.asm", "asm", "9.8")
|
||||
implementation("org.ow2.asm", "asm-tree", "9.8")
|
||||
implementation("com.dfsek.tectonic", "common", "4.2.1")
|
||||
implementation("org.yaml", "snakeyaml", "2.3")
|
||||
implementation("org.yaml", "snakeyaml", "2.4")
|
||||
}
|
@ -69,8 +69,8 @@ fun Project.configureDependencies() {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation("org.junit.jupiter", "junit-jupiter-api", Versions.Libraries.Internal.junit)
|
||||
testImplementation("org.junit.jupiter", "junit-jupiter-engine", Versions.Libraries.Internal.junit)
|
||||
testImplementation("org.junit.jupiter", "junit-jupiter", Versions.Libraries.Internal.junit)
|
||||
"testRuntimeOnly"("org.junit.platform", "junit-platform-launcher")
|
||||
compileOnly("org.jetbrains", "annotations", Versions.Libraries.Internal.jetBrainsAnnotations)
|
||||
|
||||
compileOnly("com.google.guava", "guava", Versions.Libraries.Internal.guava)
|
||||
|
@ -1,6 +1,6 @@
|
||||
object Versions {
|
||||
object Terra {
|
||||
const val overworldConfig = "v1.3.4"
|
||||
const val overworldConfig = "v1.5.1"
|
||||
}
|
||||
|
||||
object Libraries {
|
||||
@ -11,26 +11,26 @@ object Versions {
|
||||
|
||||
const val cloud = "2.0.0"
|
||||
|
||||
const val caffeine = "3.1.8"
|
||||
|
||||
const val slf4j = "2.0.16"
|
||||
const val caffeine = "3.2.0"
|
||||
|
||||
const val slf4j = "2.0.17"
|
||||
|
||||
object Internal {
|
||||
const val shadow = "8.3.3"
|
||||
const val apacheText = "1.12.0"
|
||||
const val apacheIO = "2.17.0"
|
||||
const val guava = "33.3.1-jre"
|
||||
const val asm = "9.7.1"
|
||||
const val snakeYml = "2.3"
|
||||
const val jetBrainsAnnotations = "26.0.1"
|
||||
const val junit = "5.11.3"
|
||||
const val shadow = "8.3.6"
|
||||
const val apacheText = "1.13.1"
|
||||
const val apacheIO = "2.19.0"
|
||||
const val guava = "33.4.8-jre"
|
||||
const val asm = "9.8"
|
||||
const val snakeYml = "2.4"
|
||||
const val jetBrainsAnnotations = "26.0.2"
|
||||
const val junit = "5.13.0"
|
||||
const val nbt = "6.1"
|
||||
}
|
||||
}
|
||||
|
||||
object Fabric {
|
||||
const val fabricAPI = "0.118.0+${Mod.minecraft}"
|
||||
const val cloud = "2.0.0-beta.9"
|
||||
const val fabricAPI = "0.125.3+${Mod.minecraft}"
|
||||
const val cloud = "2.0.0-beta.10"
|
||||
}
|
||||
//
|
||||
// object Quilt {
|
||||
@ -39,13 +39,13 @@ object Versions {
|
||||
// }
|
||||
|
||||
object Mod {
|
||||
const val mixin = "0.15.3+mixin.0.8.7"
|
||||
const val mixin = "0.15.5+mixin.0.8.7"
|
||||
|
||||
const val minecraft = "1.21.4"
|
||||
const val yarn = "$minecraft+build.8"
|
||||
const val fabricLoader = "0.16.10"
|
||||
const val minecraft = "1.21.5"
|
||||
const val yarn = "$minecraft+build.1"
|
||||
const val fabricLoader = "0.16.14"
|
||||
|
||||
const val architecuryLoom = "1.9.428"
|
||||
const val architecuryLoom = "1.10.431"
|
||||
const val architecturyPlugin = "3.4.161"
|
||||
|
||||
}
|
||||
@ -56,14 +56,14 @@ object Versions {
|
||||
// }
|
||||
|
||||
object Bukkit {
|
||||
const val minecraft = "1.21.4"
|
||||
const val paperBuild = "$minecraft-R0.1-20250317.101324-208"
|
||||
const val minecraft = "1.21.5-R0.1"
|
||||
const val paperBuild = "$minecraft-20250529.121722-14"
|
||||
const val paper = paperBuild
|
||||
const val paperLib = "1.0.8"
|
||||
const val reflectionRemapper = "0.1.1"
|
||||
const val paperDevBundle = paperBuild
|
||||
const val reflectionRemapper = "0.1.2"
|
||||
const val paperDevBundle = "$minecraft-20250529.121722-99"
|
||||
const val runPaper = "2.3.1"
|
||||
const val paperWeight = "2.0.0-beta.16"
|
||||
const val paperWeight = "2.0.0-beta.17"
|
||||
const val cloud = "2.0.0-beta.10"
|
||||
}
|
||||
|
||||
@ -75,18 +75,18 @@ object Versions {
|
||||
// }
|
||||
//
|
||||
object CLI {
|
||||
const val logback = "1.5.8"
|
||||
const val picocli = "4.7.6"
|
||||
const val logback = "1.5.18"
|
||||
const val picocli = "4.7.7"
|
||||
}
|
||||
|
||||
object Allay {
|
||||
const val api = "0.2.0"
|
||||
const val gson = "2.12.1"
|
||||
const val api = "0.4.1"
|
||||
const val gson = "2.13.1"
|
||||
const val mappings = "3626653"
|
||||
const val mappingsGenerator = "366618e"
|
||||
}
|
||||
|
||||
object Minestom {
|
||||
const val minestom = "187931e50b"
|
||||
const val minestom = "1_21_5-4d91778331"
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ dependencies {
|
||||
|
||||
compileOnlyApi("org.slf4j", "slf4j-api", Versions.Libraries.slf4j)
|
||||
testImplementation("org.slf4j", "slf4j-api", Versions.Libraries.slf4j)
|
||||
|
||||
api("org.incendo", "cloud-core", Versions.Libraries.cloud)
|
||||
|
||||
|
||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,7 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=7a00d51fb93147819aab76024feece20b6b84e420694101f276be952e08bef03
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
|
||||
distributionSha256Sum=845952a9d6afa783db70bb3b0effaae45ae5542ca2bb7929619e8af49cb634cf
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
9
gradlew
vendored
9
gradlew
vendored
@ -86,8 +86,7 @@ done
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||
' "$PWD" ) || exit
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
@ -115,7 +114,7 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
CLASSPATH="\\\"\\\""
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@ -206,7 +205,7 @@ fi
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
@ -214,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
|
4
gradlew.bat
vendored
4
gradlew.bat
vendored
@ -70,11 +70,11 @@ goto fail
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
set CLASSPATH=
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
@ -16,8 +16,8 @@ import org.allaymc.api.block.type.BlockStateSafeGetter;
|
||||
import org.allaymc.api.block.type.BlockTypes;
|
||||
import org.allaymc.api.item.type.ItemType;
|
||||
import org.allaymc.api.item.type.ItemTypeSafeGetter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
@ -38,7 +38,7 @@ public record AllayItemStack(ItemStack allayItemStack) implements com.dfsek.terr
|
||||
allayItemStack.addEnchantment(enchantment.getType(), enchantment.getLevel());
|
||||
}
|
||||
allayItemStack.setLore(targetItem.getLore());
|
||||
allayItemStack.setDurability(targetItem.getDurability());
|
||||
allayItemStack.setDamage(targetItem.getDamage());
|
||||
allayItemStack.setCustomName(targetItem.getCustomName());
|
||||
allayItemStack.setMeta(targetItem.getMeta());
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
shaded(project(":platforms:bukkit:common"))
|
||||
shaded(project(":platforms:bukkit:nms:v1_21_3", configuration = "reobf"))
|
||||
shaded(project(":platforms:bukkit:nms:v1_21_5", configuration = "reobf"))
|
||||
shaded("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper)
|
||||
}
|
||||
|
||||
@ -26,6 +26,11 @@ tasks {
|
||||
minecraftVersion(Versions.Bukkit.minecraft)
|
||||
dependsOn(shadowJar)
|
||||
pluginJars(shadowJar.get().archiveFile)
|
||||
|
||||
downloadPlugins {
|
||||
modrinth("viaversion", "5.3.2")
|
||||
modrinth("viabackwards", "5.3.2")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,10 +54,6 @@ public interface Initializer {
|
||||
private static Initializer constructInitializer() {
|
||||
try {
|
||||
String packageVersion = NMS;
|
||||
if (NMS.equals("v1_21_4")) {
|
||||
packageVersion = "v1_21_3";
|
||||
}
|
||||
|
||||
Class<?> initializerClass = Class.forName(TERRA_PACKAGE + "." + packageVersion + ".NMSInitializer");
|
||||
try {
|
||||
return (Initializer) initializerClass.getConstructor().newInstance();
|
||||
|
@ -2,7 +2,7 @@ name: "Terra"
|
||||
main: "com.dfsek.terra.bukkit.TerraBukkitPlugin"
|
||||
version: "@VERSION@"
|
||||
load: "STARTUP"
|
||||
authors: [ "dfsek", "duplexsystem", "Astrash", "solonovamax", "Sancires", "Aureus", "RogueShade" ]
|
||||
authors: [ "dfsek", "duplexsystem", "Astrash", "solonovamax", "Sancires", "Aureus", "RogueShade", "OakLoaf" ]
|
||||
website: "@WIKI@"
|
||||
api-version: "1.21.1"
|
||||
description: "@DESCRIPTION@"
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5;
|
||||
|
||||
import com.dfsek.terra.bukkit.nms.v1_21_3.config.VanillaBiomeProperties;
|
||||
import com.dfsek.terra.bukkit.nms.v1_21_5.config.VanillaBiomeProperties;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Holder.Reference;
|
@ -1,11 +1,11 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5;
|
||||
|
||||
import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
|
||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.bukkit.BukkitAddon;
|
||||
import com.dfsek.terra.bukkit.PlatformImpl;
|
||||
import com.dfsek.terra.bukkit.nms.v1_21_3.config.VanillaBiomeProperties;
|
||||
import com.dfsek.terra.bukkit.nms.v1_21_5.config.VanillaBiomeProperties;
|
||||
|
||||
|
||||
public class NMSAddon extends BukkitAddon {
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5;
|
||||
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
@ -12,7 +12,7 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.bukkit.nms.v1_21_3.config.VanillaBiomeProperties;
|
||||
import com.dfsek.terra.bukkit.nms.v1_21_5.config.VanillaBiomeProperties;
|
||||
|
||||
|
||||
public class NMSBiomeInjector {
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.core.Holder;
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@ -116,10 +116,10 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||
if(noise > threshold) {
|
||||
chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate
|
||||
.getPalette(x + xi, y, z + zi, world, biomeProvider)
|
||||
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
|
||||
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), 0);
|
||||
depth++;
|
||||
} else if(noise < airThreshold) {
|
||||
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false);
|
||||
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), 0);
|
||||
} else {
|
||||
depth = 0;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5;
|
||||
|
||||
import com.dfsek.terra.bukkit.BukkitAddon;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5;
|
||||
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ServerLevel;
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5;
|
||||
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Holder.Reference;
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.Registries;
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
@ -7,7 +7,7 @@ import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData;
|
||||
|
||||
|
||||
public class SpawnEntryTemplate implements ObjectTemplate<SpawnerData> {
|
||||
public class SpawnEntryConfig implements ObjectTemplate<SpawnEntryConfig> {
|
||||
@Value("type")
|
||||
@Default
|
||||
private EntityType<?> type = null;
|
||||
@ -23,9 +23,17 @@ public class SpawnEntryTemplate implements ObjectTemplate<SpawnerData> {
|
||||
@Value("max-group-size")
|
||||
@Default
|
||||
private Integer maxGroupSize = null;
|
||||
|
||||
public Integer getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public SpawnerData getSpawnerData() {
|
||||
return new SpawnerData(type, minGroupSize, maxGroupSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpawnerData get() {
|
||||
return new SpawnerData(type, weight, minGroupSize, maxGroupSize);
|
||||
public SpawnEntryConfig get() {
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
@ -6,7 +6,6 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import java.util.List;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -33,8 +32,8 @@ public class SpawnSettingsTemplate implements ObjectTemplate<MobSpawnSettings> {
|
||||
MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder();
|
||||
for(SpawnTypeConfig spawn : spawns) {
|
||||
MobCategory group = spawn.getGroup();
|
||||
for(SpawnerData entry : spawn.getEntries()) {
|
||||
builder.addSpawn(group, entry);
|
||||
for(SpawnEntryConfig entry : spawn.getEntries()) {
|
||||
builder.addSpawn(group, entry.getWeight(), entry.getSpawnerData());
|
||||
}
|
||||
}
|
||||
for(SpawnCostConfig cost : costs) {
|
@ -1,11 +1,10 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import java.util.List;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData;
|
||||
|
||||
|
||||
public class SpawnTypeConfig implements ObjectTemplate<SpawnTypeConfig> {
|
||||
@ -15,13 +14,13 @@ public class SpawnTypeConfig implements ObjectTemplate<SpawnTypeConfig> {
|
||||
|
||||
@Value("entries")
|
||||
@Default
|
||||
private List<SpawnerData> entries = null;
|
||||
private List<SpawnEntryConfig> entries = null;
|
||||
|
||||
public MobCategory getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public List<SpawnerData> getEntries() {
|
||||
public List<SpawnEntryConfig> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.ConfigTemplate;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
@ -11,7 +11,8 @@
|
||||
"solonovamax",
|
||||
"Sancires",
|
||||
"Aureus",
|
||||
"RogueShade"
|
||||
"RogueShade",
|
||||
"OakLoaf"
|
||||
],
|
||||
"contact": {
|
||||
"homepage": "@WIKI@",
|
||||
@ -34,7 +35,7 @@
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.10",
|
||||
"java": ">=21",
|
||||
"minecraft": ">=1.21.4",
|
||||
"minecraft": ">=1.21.5",
|
||||
"fabric": "*"
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import net.minestom.server.command.builder.Command;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.entity.GameMode;
|
||||
import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
|
||||
import net.minestom.server.event.player.PlayerDisconnectEvent;
|
||||
import net.minestom.server.event.player.PlayerSpawnEvent;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.instance.LightingChunk;
|
||||
@ -16,7 +17,6 @@ import java.time.Duration;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.dfsek.terra.minestom.world.TerraMinestomWorld;
|
||||
import com.dfsek.terra.minestom.world.TerraMinestomWorldBuilder;
|
||||
|
||||
|
||||
public class TerraMinestomExample {
|
||||
@ -24,6 +24,7 @@ public class TerraMinestomExample {
|
||||
private final MinecraftServer server = MinecraftServer.init();
|
||||
private Instance instance;
|
||||
private TerraMinestomWorld world;
|
||||
private final TerraMinestomPlatform platform = new TerraMinestomPlatform();
|
||||
|
||||
public void createNewInstance() {
|
||||
instance = MinecraftServer.getInstanceManager().createInstanceContainer();
|
||||
@ -31,8 +32,9 @@ public class TerraMinestomExample {
|
||||
}
|
||||
|
||||
public void attachTerra() {
|
||||
world = TerraMinestomWorldBuilder.from(instance)
|
||||
world = platform.worldBuilder(instance)
|
||||
.defaultPack()
|
||||
.doFineGrainedBiomes(false)
|
||||
.attach();
|
||||
}
|
||||
|
||||
@ -121,12 +123,16 @@ public class TerraMinestomExample {
|
||||
|
||||
private void regenerate() {
|
||||
instance.sendMessage(Component.text("Regenerating world"));
|
||||
Instance oldInstance = instance;
|
||||
platform.reload();
|
||||
createNewInstance();
|
||||
attachTerra();
|
||||
preloadWorldAndMeasure();
|
||||
MinecraftServer.getConnectionManager().getOnlinePlayers().forEach(player ->
|
||||
player.setInstance(instance, new Pos(0, 100, 0))
|
||||
);
|
||||
|
||||
MinecraftServer.getInstanceManager().unregisterInstance(oldInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,93 +0,0 @@
|
||||
package com.dfsek.terra.minestom;
|
||||
|
||||
import com.dfsek.tectonic.api.TypeRegistry;
|
||||
import com.dfsek.tectonic.api.loader.type.TypeLoader;
|
||||
import com.dfsek.terra.AbstractPlatform;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.entity.EntityType;
|
||||
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
|
||||
import com.dfsek.terra.api.handle.ItemHandle;
|
||||
import com.dfsek.terra.api.handle.WorldHandle;
|
||||
import com.dfsek.terra.api.world.biome.PlatformBiome;
|
||||
import com.dfsek.terra.minestom.biome.MinestomBiomeLoader;
|
||||
import com.dfsek.terra.minestom.entity.MinestomEntityType;
|
||||
import com.dfsek.terra.minestom.item.MinestomItemHandle;
|
||||
import com.dfsek.terra.minestom.world.MinestomChunkGeneratorWrapper;
|
||||
import com.dfsek.terra.minestom.world.MinestomWorldHandle;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
public final class MinestomPlatform extends AbstractPlatform {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MinestomPlatform.class);
|
||||
private static MinestomPlatform INSTANCE = null;
|
||||
private final MinestomWorldHandle worldHandle = new MinestomWorldHandle();
|
||||
private final MinestomItemHandle itemHandle = new MinestomItemHandle();
|
||||
|
||||
private MinestomPlatform() {
|
||||
load();
|
||||
getEventManager().callEvent(new PlatformInitializationEvent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(TypeRegistry registry) {
|
||||
super.register(registry);
|
||||
registry
|
||||
.registerLoader(PlatformBiome.class, new MinestomBiomeLoader())
|
||||
.registerLoader(EntityType.class, (TypeLoader<EntityType>) (annotatedType, o, configLoader, depthTracker) -> new MinestomEntityType((String) o))
|
||||
.registerLoader(BlockState.class, (TypeLoader<BlockState>) (annotatedType, o, configLoader, depthTracker) -> worldHandle.createBlockState((String) o));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reload() {
|
||||
getTerraConfig().load(this);
|
||||
boolean succeed = loadConfigPacks();
|
||||
|
||||
MinecraftServer.getInstanceManager().getInstances().forEach(world -> {
|
||||
if(world.generator() instanceof MinestomChunkGeneratorWrapper wrapper) {
|
||||
getConfigRegistry().get(wrapper.getPack().getRegistryKey()).ifPresent(pack -> {
|
||||
wrapper.setPack(pack);
|
||||
LOGGER.info("Replaced pack in chunk generator for instance {}", world.getUniqueId());
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return succeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull WorldHandle getWorldHandle() {
|
||||
return worldHandle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemHandle getItemHandle() {
|
||||
return itemHandle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String platformName() {
|
||||
return "Minestom";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull File getDataFolder() {
|
||||
String pathName = System.getProperty("terra.datafolder");
|
||||
if (pathName == null) pathName = "./terra/";
|
||||
File file = new File(pathName);
|
||||
if(!file.exists()) file.mkdirs();
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
public static MinestomPlatform getInstance() {
|
||||
if(INSTANCE == null) {
|
||||
INSTANCE = new MinestomPlatform();
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
package com.dfsek.terra.minestom;
|
||||
|
||||
import com.dfsek.tectonic.api.TypeRegistry;
|
||||
import com.dfsek.tectonic.api.loader.type.TypeLoader;
|
||||
|
||||
import com.dfsek.terra.AbstractPlatform;
|
||||
import com.dfsek.terra.api.addon.BaseAddon;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.entity.EntityType;
|
||||
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
|
||||
import com.dfsek.terra.api.handle.ItemHandle;
|
||||
import com.dfsek.terra.api.handle.WorldHandle;
|
||||
import com.dfsek.terra.api.world.biome.PlatformBiome;
|
||||
import com.dfsek.terra.minestom.addon.MinestomAddon;
|
||||
import com.dfsek.terra.minestom.config.BiomeAdditionsSoundTemplate;
|
||||
import com.dfsek.terra.minestom.config.BiomeParticleConfigTemplate;
|
||||
import com.dfsek.terra.minestom.biome.MinestomBiomeLoader;
|
||||
import com.dfsek.terra.minestom.config.KeyLoader;
|
||||
import com.dfsek.terra.minestom.config.BiomeMoodSoundTemplate;
|
||||
import com.dfsek.terra.minestom.config.RGBLikeLoader;
|
||||
import com.dfsek.terra.minestom.config.SoundEventTemplate;
|
||||
import com.dfsek.terra.minestom.entity.MinestomEntityType;
|
||||
import com.dfsek.terra.minestom.item.MinestomItemHandle;
|
||||
import com.dfsek.terra.minestom.world.MinestomChunkGeneratorWrapper;
|
||||
import com.dfsek.terra.minestom.world.MinestomWorldHandle;
|
||||
|
||||
import com.dfsek.terra.minestom.api.TerraMinestomWorldBuilder;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.util.RGBLike;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.sound.SoundEvent;
|
||||
import net.minestom.server.world.biome.BiomeEffects;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public final class TerraMinestomPlatform extends AbstractPlatform {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TerraMinestomPlatform.class);
|
||||
private final WorldHandle worldHandle;
|
||||
private final ItemHandle itemHandle;
|
||||
private final TypeLoader<PlatformBiome> biomeTypeLoader;
|
||||
private final ArrayList<BaseAddon> platformAddons = new ArrayList<>(List.of(new MinestomAddon(this)));
|
||||
|
||||
public TerraMinestomPlatform(WorldHandle worldHandle, ItemHandle itemHandle, TypeLoader<PlatformBiome> biomeTypeLoader, BaseAddon... extraAddons) {
|
||||
this.worldHandle = worldHandle;
|
||||
this.itemHandle = itemHandle;
|
||||
this.biomeTypeLoader = biomeTypeLoader;
|
||||
this.platformAddons.addAll(List.of(extraAddons));
|
||||
load();
|
||||
getEventManager().callEvent(new PlatformInitializationEvent());
|
||||
}
|
||||
|
||||
public TerraMinestomPlatform() {
|
||||
this(new MinestomWorldHandle(), new MinestomItemHandle(), new MinestomBiomeLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(TypeRegistry registry) {
|
||||
super.register(registry);
|
||||
registry
|
||||
.registerLoader(PlatformBiome.class, biomeTypeLoader)
|
||||
.registerLoader(RGBLike.class, new RGBLikeLoader())
|
||||
.registerLoader(Key.class, new KeyLoader())
|
||||
.registerLoader(EntityType.class, (TypeLoader<EntityType>) (annotatedType, o, configLoader, depthTracker) -> new MinestomEntityType((String) o))
|
||||
.registerLoader(BlockState.class, (TypeLoader<BlockState>) (annotatedType, o, configLoader, depthTracker) -> worldHandle.createBlockState((String) o))
|
||||
.registerLoader(BiomeEffects.Particle.class, BiomeParticleConfigTemplate::new)
|
||||
.registerLoader(BiomeEffects.MoodSound.class, BiomeMoodSoundTemplate::new)
|
||||
.registerLoader(BiomeEffects.AdditionsSound.class, BiomeAdditionsSoundTemplate::new)
|
||||
.registerLoader(SoundEvent.class, SoundEventTemplate::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reload() {
|
||||
getTerraConfig().load(this);
|
||||
boolean succeed = loadConfigPacks();
|
||||
|
||||
MinecraftServer.getInstanceManager().getInstances().forEach(world -> {
|
||||
if(world.generator() instanceof MinestomChunkGeneratorWrapper wrapper) {
|
||||
getConfigRegistry().get(wrapper.getPack().getRegistryKey()).ifPresent(pack -> {
|
||||
wrapper.setPack(pack);
|
||||
LOGGER.info("Replaced pack in chunk generator for instance {}", world.getUuid());
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return succeed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull WorldHandle getWorldHandle() {
|
||||
return worldHandle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemHandle getItemHandle() {
|
||||
return itemHandle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String platformName() {
|
||||
return "Minestom";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull File getDataFolder() {
|
||||
String pathName = System.getProperty("terra.datafolder");
|
||||
if(pathName == null) pathName = "./terra/";
|
||||
File file = new File(pathName);
|
||||
if(!file.exists()) file.mkdirs();
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<BaseAddon> platformAddon() {
|
||||
return platformAddons;
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder worldBuilder(Instance instance) {
|
||||
return new TerraMinestomWorldBuilder(this, instance);
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder worldBuilder() {
|
||||
return new TerraMinestomWorldBuilder(this, MinecraftServer.getInstanceManager().createInstanceContainer());
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.dfsek.terra.minestom.addon;
|
||||
|
||||
import ca.solostudios.strata.Versions;
|
||||
import ca.solostudios.strata.version.Version;
|
||||
|
||||
import com.dfsek.terra.api.addon.BaseAddon;
|
||||
|
||||
import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
|
||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
import com.dfsek.terra.minestom.TerraMinestomPlatform;
|
||||
|
||||
import com.dfsek.terra.minestom.config.VanillaBiomeProperties;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
public class MinestomAddon implements BaseAddon {
|
||||
private static final Version VERSION = Versions.getVersion(1, 0, 0);
|
||||
private static final Logger logger = LoggerFactory.getLogger(MinestomAddon.class);
|
||||
private final TerraMinestomPlatform minestomPlatform;
|
||||
|
||||
public MinestomAddon(TerraMinestomPlatform minestomPlatform) {
|
||||
this.minestomPlatform = minestomPlatform;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
minestomPlatform.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(this, ConfigurationLoadEvent.class)
|
||||
.then(event -> {
|
||||
if(event.is(Biome.class)) {
|
||||
event.getLoadedObject(Biome.class).getContext().put(event.load(new VanillaBiomeProperties()));
|
||||
}
|
||||
})
|
||||
.global();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Version getVersion() { return VERSION; }
|
||||
|
||||
@Override
|
||||
public String getID() { return "terra-minestom"; }
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.dfsek.terra.minestom.api;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.minestom.biome.UserDefinedBiome;
|
||||
|
||||
|
||||
/**
|
||||
* BiomeFactory serves as a contract for creating custom user-defined biomes in Terra.
|
||||
* Implementations of this interface are responsible for defining the logic to convert
|
||||
* configured biomes and source biome data into instances of UserDefinedBiome.
|
||||
*/
|
||||
public interface BiomeFactory {
|
||||
UserDefinedBiome create(ConfigPack pack, Biome source);
|
||||
}
|
@ -8,8 +8,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a factory interface for creating instances of BlockEntity
|
||||
* at a specified BlockVec position. This is not implemented directly because
|
||||
* Minestom does not define a way to build block entities out of the box.
|
||||
* at a specified BlockVec position. For more fine-grained control, users
|
||||
* may supply their own version of this interface.
|
||||
*/
|
||||
public interface BlockEntityFactory {
|
||||
@Nullable BlockEntity createBlockEntity(BlockVec position);
|
||||
|
@ -0,0 +1,91 @@
|
||||
package com.dfsek.terra.minestom.api;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
|
||||
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||
|
||||
import com.dfsek.terra.minestom.TerraMinestomPlatform;
|
||||
import com.dfsek.terra.minestom.biome.MinestomUserDefinedBiomeFactory;
|
||||
import com.dfsek.terra.minestom.block.DefaultBlockEntityFactory;
|
||||
import com.dfsek.terra.minestom.entity.DefaultEntityFactory;
|
||||
|
||||
import com.dfsek.terra.minestom.world.TerraMinestomWorld;
|
||||
import net.minestom.server.instance.Instance;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
||||
public class TerraMinestomWorldBuilder {
|
||||
private final TerraMinestomPlatform platform;
|
||||
private final Instance instance;
|
||||
private ConfigPack pack;
|
||||
private long seed = new Random().nextLong();
|
||||
private EntityFactory entityFactory = new DefaultEntityFactory();
|
||||
private BlockEntityFactory blockEntityFactory;
|
||||
private BiomeFactory biomeFactory = new MinestomUserDefinedBiomeFactory();
|
||||
private boolean doFineGrainedBiomes = true;
|
||||
|
||||
public TerraMinestomWorldBuilder(TerraMinestomPlatform platform, Instance instance) {
|
||||
this.platform = platform;
|
||||
this.instance = instance;
|
||||
this.blockEntityFactory = new DefaultBlockEntityFactory(instance);
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder pack(ConfigPack pack) {
|
||||
this.pack = pack;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder packById(String id) {
|
||||
this.pack = platform.getConfigRegistry().getByID(id).orElseThrow();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder findPack(Function<CheckedRegistry<ConfigPack>, ConfigPack> fn) {
|
||||
this.pack = fn.apply(platform.getConfigRegistry());
|
||||
return this;
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder defaultPack() {
|
||||
return this.packById("OVERWORLD");
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder seed(long seed) {
|
||||
this.seed = seed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder entityFactory(EntityFactory factory) {
|
||||
this.entityFactory = factory;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder blockEntityFactory(BlockEntityFactory factory) {
|
||||
this.blockEntityFactory = factory;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder biomeFactory(BiomeFactory factory) {
|
||||
this.biomeFactory = factory;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Due to a current bug with the minestom biome encoder, sometimes, the client gets kicked when decoding a chunk
|
||||
* packet with more than one biome. Until this is fixed in minestom, one can disable fine-grained biomes to prevent
|
||||
* this issue.
|
||||
*
|
||||
* @deprecated Scheduled for removal once Minestom rolls out a fix
|
||||
*/
|
||||
@Deprecated
|
||||
public TerraMinestomWorldBuilder doFineGrainedBiomes(boolean doFineGrainedBiomes) {
|
||||
this.doFineGrainedBiomes = doFineGrainedBiomes;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TerraMinestomWorld attach() {
|
||||
return new TerraMinestomWorld(platform, instance, pack, seed, entityFactory, blockEntityFactory, biomeFactory, doFineGrainedBiomes);
|
||||
}
|
||||
}
|
@ -2,16 +2,17 @@ package com.dfsek.terra.minestom.biome;
|
||||
|
||||
import com.dfsek.terra.api.world.biome.PlatformBiome;
|
||||
|
||||
import net.minestom.server.registry.DynamicRegistry;
|
||||
import net.minestom.server.world.biome.Biome;
|
||||
|
||||
|
||||
public class MinestomBiome implements PlatformBiome {
|
||||
private final Biome biome;
|
||||
private final DynamicRegistry.Key<Biome> biome;
|
||||
|
||||
public MinestomBiome(Biome biome) { this.biome = biome; }
|
||||
public MinestomBiome(DynamicRegistry.Key<Biome> biome) { this.biome = biome; }
|
||||
|
||||
@Override
|
||||
public Biome getHandle() {
|
||||
public DynamicRegistry.Key<Biome> getHandle() {
|
||||
return biome;
|
||||
}
|
||||
}
|
||||
|
@ -7,25 +7,20 @@ import com.dfsek.tectonic.api.loader.type.TypeLoader;
|
||||
|
||||
import com.dfsek.terra.api.world.biome.PlatformBiome;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minestom.server.registry.DynamicRegistry;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import net.minestom.server.world.biome.Biome;
|
||||
import org.intellij.lang.annotations.Subst;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
|
||||
|
||||
public class MinestomBiomeLoader implements TypeLoader<PlatformBiome> {
|
||||
private final DynamicRegistry<Biome> biomeRegistry = MinecraftServer.getBiomeRegistry();
|
||||
|
||||
@Override
|
||||
public PlatformBiome load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader,
|
||||
DepthTracker depthTracker) throws LoadException {
|
||||
@Subst("name:value")
|
||||
String id = (String) o;
|
||||
NamespaceID biomeID = NamespaceID.from(id);
|
||||
Biome biome = biomeRegistry.get(biomeID);
|
||||
if(biome == null) throw new LoadException("Biome %s does not exist in registry".formatted(id), depthTracker);
|
||||
return new MinestomBiome(biome);
|
||||
Key key = Key.key(id);
|
||||
return new MinestomBiome(DynamicRegistry.Key.of(key));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package com.dfsek.terra.minestom.biome;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.minestom.api.BiomeFactory;
|
||||
import com.dfsek.terra.minestom.config.VanillaBiomeProperties;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.color.Color;
|
||||
import net.minestom.server.registry.DynamicRegistry;
|
||||
import net.minestom.server.world.biome.Biome;
|
||||
import net.minestom.server.world.biome.BiomeEffects;
|
||||
import org.intellij.lang.annotations.Subst;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
public class MinestomUserDefinedBiomeFactory implements BiomeFactory {
|
||||
private final DynamicRegistry<Biome> biomeRegistry = MinecraftServer.getBiomeRegistry();
|
||||
private final @NotNull Biome plainsBiome = Objects.requireNonNull(biomeRegistry.get(Key.key("minecraft:plains")));
|
||||
|
||||
@Override
|
||||
public UserDefinedBiome create(ConfigPack pack, com.dfsek.terra.api.world.biome.Biome source) {
|
||||
VanillaBiomeProperties properties = source.getContext().get(VanillaBiomeProperties.class);
|
||||
DynamicRegistry.Key<Biome> parentKey = ((MinestomBiome) source.getPlatformBiome()).getHandle();
|
||||
Biome parent = mergeNullable(biomeRegistry.get(parentKey), plainsBiome);
|
||||
BiomeEffects parentEffects = parent.effects();
|
||||
Key key = Key.key("terra", createBiomeID(pack, source.getID()));
|
||||
|
||||
BiomeEffects.Builder effectsBuilder = BiomeEffects.builder()
|
||||
.fogColor(mergeNullable(properties.getFogColor(), parentEffects.fogColor()))
|
||||
.skyColor(mergeNullable(properties.getSkyColor(), parentEffects.skyColor()))
|
||||
.waterColor(mergeNullable(properties.getWaterColor(), parentEffects.waterColor()))
|
||||
.waterFogColor(mergeNullable(properties.getWaterFogColor(), parentEffects.waterFogColor()))
|
||||
.foliageColor(mergeNullable(properties.getFoliageColor(), parentEffects.foliageColor()))
|
||||
.grassColor(mergeNullable(properties.getGrassColor(), parentEffects.grassColor()))
|
||||
.grassColorModifier(mergeNullable(properties.getGrassColorModifier(), parentEffects.grassColorModifier()))
|
||||
.biomeParticle(mergeNullable(properties.getParticleConfig(), parentEffects.biomeParticle()))
|
||||
.ambientSound(mergeNullable(properties.getLoopSound(), parentEffects.ambientSound()))
|
||||
.moodSound(mergeNullable(properties.getMoodSound(), parentEffects.moodSound()))
|
||||
.additionsSound(mergeNullable(properties.getAdditionsSound(), parentEffects.additionsSound()))
|
||||
// TODO music
|
||||
.music(parentEffects.music())
|
||||
.musicVolume(parentEffects.musicVolume());
|
||||
|
||||
if (effectsBuilder.build().equals(BiomeEffects.PLAINS_EFFECTS)) {
|
||||
effectsBuilder.fogColor(new Color(0xC0D8FE)); // circumvent a minestom bug
|
||||
}
|
||||
|
||||
Biome target = Biome.builder()
|
||||
.downfall(mergeNullable(properties.getDownfall(), parent.downfall()))
|
||||
.hasPrecipitation(mergeNullable(properties.getPrecipitation(), parent.hasPrecipitation()))
|
||||
.temperature(mergeNullable(properties.getTemperature(), parent.temperature()))
|
||||
.temperatureModifier(mergeNullable(properties.getTemperatureModifier(), parent.temperatureModifier()))
|
||||
.effects(effectsBuilder.build())
|
||||
.build();
|
||||
|
||||
DynamicRegistry.Key<Biome> registryKey = MinecraftServer.getBiomeRegistry().register(key, target);
|
||||
return new UserDefinedBiome(key, registryKey, source.getID(), target);
|
||||
}
|
||||
|
||||
private static <T> T mergeNullable(T first, T second) {
|
||||
if (first == null) return second;
|
||||
return first;
|
||||
}
|
||||
|
||||
@Subst("value")
|
||||
protected static String createBiomeID(ConfigPack pack, String biomeId) {
|
||||
return pack.getID().toLowerCase() + "/" + biomeId.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.dfsek.terra.minestom.biome;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.minestom.api.BiomeFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
public class MinestomUserDefinedBiomePool {
|
||||
private final HashMap<String, UserDefinedBiome> biomes = new HashMap<>();
|
||||
private final BiomeFactory factory;
|
||||
private final ConfigPack configPack;
|
||||
|
||||
public MinestomUserDefinedBiomePool(ConfigPack configPack, BiomeFactory factory) {
|
||||
this.configPack = configPack;
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public UserDefinedBiome getBiome(Biome source) {
|
||||
UserDefinedBiome userDefinedBiome = biomes.get(source.getID());
|
||||
if(userDefinedBiome != null) return userDefinedBiome;
|
||||
userDefinedBiome = factory.create(configPack, source);
|
||||
biomes.put(source.getID(), userDefinedBiome);
|
||||
return userDefinedBiome;
|
||||
}
|
||||
|
||||
public void preloadBiomes(Iterable<Biome> biomesToLoad) {
|
||||
biomesToLoad
|
||||
.forEach(biome -> {
|
||||
if(!this.biomes.containsKey(biome.getID())) {
|
||||
this.biomes.put(biome.getID(), factory.create(configPack, biome));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void invalidate() {
|
||||
biomes.clear();
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.dfsek.terra.minestom.biome;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minestom.server.registry.DynamicRegistry;
|
||||
import net.minestom.server.world.biome.Biome;
|
||||
|
||||
|
||||
public record UserDefinedBiome(Key key, DynamicRegistry.Key<Biome> registry, String id, Biome biome) {
|
||||
}
|
@ -4,11 +4,18 @@ import com.dfsek.terra.api.block.entity.BlockEntity;
|
||||
import com.dfsek.terra.minestom.api.BlockEntityFactory;
|
||||
|
||||
import net.minestom.server.coordinate.BlockVec;
|
||||
import net.minestom.server.instance.Instance;
|
||||
|
||||
|
||||
public class DefaultBlockEntityFactory implements BlockEntityFactory {
|
||||
private final Instance instance;
|
||||
|
||||
public DefaultBlockEntityFactory(Instance instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity createBlockEntity(BlockVec position) {
|
||||
return null;
|
||||
return new MinestomBlockEntity(instance, position);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
package com.dfsek.terra.minestom.block;
|
||||
|
||||
import com.dfsek.seismic.type.vector.Vector3;
|
||||
|
||||
import com.dfsek.terra.api.block.entity.BlockEntity;
|
||||
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
|
||||
import net.minestom.server.coordinate.BlockVec;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
|
||||
|
||||
public class MinestomBlockEntity implements BlockEntity {
|
||||
private final Instance instance;
|
||||
private final BlockVec position;
|
||||
private final Vector3 positionVec;
|
||||
|
||||
public MinestomBlockEntity(Instance instance, BlockVec position) {
|
||||
this.instance = instance;
|
||||
this.position = position;
|
||||
this.positionVec = Vector3.of(position.blockX(), position.blockY(), position.blockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(boolean applyPhysics) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3 getPosition() {
|
||||
return positionVec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return position.blockX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY() {
|
||||
return position.blockY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return position.blockZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState() {
|
||||
return new MinestomBlockState(instance.getBlock(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getHandle() {
|
||||
return instance.getBlock(position);
|
||||
}
|
||||
}
|
@ -24,14 +24,14 @@ public class MinestomBlockState implements BlockState {
|
||||
|
||||
public MinestomBlockState(String data) {
|
||||
if(!data.contains("[")) {
|
||||
block = Block.fromNamespaceId(data);
|
||||
block = Block.fromKey(data);
|
||||
return;
|
||||
}
|
||||
|
||||
String[] split = data.split("\\[");
|
||||
String namespaceId = split[0];
|
||||
String properties = split[1].substring(0, split[1].length() - 1);
|
||||
Block block = Block.fromNamespaceId(namespaceId);
|
||||
Block block = Block.fromKey(namespaceId);
|
||||
HashMap<String, String> propertiesMap = new HashMap<>();
|
||||
|
||||
for(String property : properties.split(",")) {
|
||||
@ -70,7 +70,7 @@ public class MinestomBlockState implements BlockState {
|
||||
|
||||
@Override
|
||||
public String getAsString(boolean properties) {
|
||||
String name = block.namespace().asString();
|
||||
String name = block.key().asString();
|
||||
if(!properties || block.properties().isEmpty()) {
|
||||
return name;
|
||||
}
|
||||
@ -95,4 +95,4 @@ public class MinestomBlockState implements BlockState {
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(block.id());
|
||||
}
|
||||
}
|
||||
}
|
@ -41,7 +41,7 @@ public class MinestomBlockType implements BlockType {
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj instanceof MinestomBlockType other) {
|
||||
return block.id() == other.block.id();
|
||||
return block.stateId() == other.block.stateId();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -3,47 +3,53 @@ package com.dfsek.terra.minestom.chunk;
|
||||
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
|
||||
import com.dfsek.terra.api.util.Column;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ProtoChunk;
|
||||
import com.dfsek.terra.minestom.biome.MinestomBiome;
|
||||
import com.dfsek.terra.minestom.block.MinestomBlockState;
|
||||
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.generator.GenerationUnit;
|
||||
import net.minestom.server.instance.generator.UnitModifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
public class CachedChunk implements ProtoChunk {
|
||||
private final int minHeight;
|
||||
private final int maxHeight;
|
||||
private final Block[][][] blocks;
|
||||
private final Block[] blocks;
|
||||
|
||||
public CachedChunk(int minHeight, int maxHeight) {
|
||||
this.minHeight = minHeight;
|
||||
this.maxHeight = maxHeight;
|
||||
this.blocks = new Block[16][maxHeight - minHeight + 1][16];
|
||||
|
||||
for(int x = 0; x < 16; x++) {
|
||||
for(int z = 0; z < 16; z++) {
|
||||
for(int y = 0; y < maxHeight - minHeight + 1; y++) {
|
||||
blocks[x][y][z] = Block.AIR;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.blocks = new Block[16 * (maxHeight - minHeight + 1) * 16];
|
||||
Arrays.fill(blocks, Block.AIR);
|
||||
}
|
||||
|
||||
public void writeRelative(UnitModifier modifier) {
|
||||
modifier.setAllRelative((x, y, z) -> blocks[x][y][z]);
|
||||
modifier.setAllRelative((x, y, z) -> blocks[getIndex(x, y + minHeight, z)]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, @NotNull BlockState blockState) {
|
||||
Block block = (Block) blockState.getHandle();
|
||||
if(block == null) return;
|
||||
blocks[x][y - minHeight][z] = block;
|
||||
blocks[getIndex(x, y, z)] = block;
|
||||
}
|
||||
|
||||
private int getIndex(int x, int y, int z) {
|
||||
int y_normalized = y - minHeight;
|
||||
return x + (z * 16) + (y_normalized * 256);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull BlockState getBlock(int x, int y, int z) {
|
||||
return new MinestomBlockState(blocks[x][y - minHeight][z]);
|
||||
return new MinestomBlockState(blocks[getIndex(x, y, z)]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -22,13 +22,15 @@ public class GeneratedChunkCache {
|
||||
private final ServerWorld world;
|
||||
private final BiomeProvider biomeProvider;
|
||||
|
||||
public GeneratedChunkCache(DimensionType dimensionType, ChunkGenerator generator, ServerWorld world) {
|
||||
public GeneratedChunkCache(DimensionType dimensionType, ChunkGenerator generator, ServerWorld world, BiomeProvider biomeProvider) {
|
||||
this.dimensionType = dimensionType;
|
||||
this.generator = generator;
|
||||
this.world = world;
|
||||
this.biomeProvider = world.getBiomeProvider();
|
||||
this.cache = Caffeine.newBuilder().maximumSize(128).recordStats().build(
|
||||
(Pair<Integer, Integer> key) -> generateChunk(key.getLeft(), key.getRight()));
|
||||
this.biomeProvider = biomeProvider;
|
||||
this.cache = Caffeine.newBuilder()
|
||||
.maximumSize(128)
|
||||
.recordStats()
|
||||
.build((Pair<Integer, Integer> key) -> generateChunk(key.getLeft(), key.getRight()));
|
||||
}
|
||||
|
||||
private CachedChunk generateChunk(int x, int z) {
|
||||
@ -39,8 +41,13 @@ public class GeneratedChunkCache {
|
||||
|
||||
public void displayStats() {
|
||||
CacheStats stats = cache.stats();
|
||||
log.info("Avg load time: {}ms | Hit rate: {}% | Load Count: {}", stats.averageLoadPenalty(), stats.hitRate() * 100,
|
||||
stats.loadCount());
|
||||
log.info("Avg load time: %.4fms | Hit rate: %3.4f%% | Load Count: %d"
|
||||
.formatted(
|
||||
stats.averageLoadPenalty() / 1000000f,
|
||||
stats.hitRate() * 100,
|
||||
stats.loadCount()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public CachedChunk at(int x, int z) {
|
||||
|
@ -0,0 +1,24 @@
|
||||
package com.dfsek.terra.minestom.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minestom.server.sound.SoundEvent;
|
||||
import net.minestom.server.world.biome.BiomeEffects;
|
||||
|
||||
|
||||
public class BiomeAdditionsSoundTemplate implements ObjectTemplate<BiomeEffects.AdditionsSound> {
|
||||
@Value("sound")
|
||||
@Default
|
||||
private SoundEvent sound = null;
|
||||
|
||||
@Value("sound-chance")
|
||||
@Default
|
||||
private Double soundChance = null;
|
||||
|
||||
@Override
|
||||
public BiomeEffects.AdditionsSound get() {
|
||||
if(sound == null) return null;
|
||||
return new BiomeEffects.AdditionsSound(sound, soundChance);
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.dfsek.terra.minestom.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minestom.server.sound.SoundEvent;
|
||||
import net.minestom.server.world.biome.BiomeEffects;
|
||||
|
||||
|
||||
public class BiomeMoodSoundTemplate implements ObjectTemplate<BiomeEffects.MoodSound> {
|
||||
@Value("sound")
|
||||
@Default
|
||||
private SoundEvent sound = null;
|
||||
|
||||
@Value("cultivation-ticks")
|
||||
@Default
|
||||
private Integer soundCultivationTicks = null;
|
||||
|
||||
@Value("spawn-range")
|
||||
@Default
|
||||
private Integer soundSpawnRange = null;
|
||||
|
||||
@Value("extra-distance")
|
||||
@Default
|
||||
private Double soundExtraDistance = null;
|
||||
|
||||
@Override
|
||||
public BiomeEffects.MoodSound get() {
|
||||
if(sound == null) return null;
|
||||
return new BiomeEffects.MoodSound(
|
||||
sound,
|
||||
soundCultivationTicks,
|
||||
soundSpawnRange,
|
||||
soundExtraDistance
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.dfsek.terra.minestom.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minestom.server.particle.Particle;
|
||||
import net.minestom.server.world.biome.BiomeEffects;
|
||||
|
||||
|
||||
public class BiomeParticleConfigTemplate implements ObjectTemplate<BiomeEffects.Particle> {
|
||||
@Value("particle")
|
||||
@Default
|
||||
private String particle = null;
|
||||
|
||||
@Value("probability")
|
||||
@Default
|
||||
private Float probability = null;
|
||||
|
||||
@Override
|
||||
public BiomeEffects.Particle get() {
|
||||
if(particle == null || probability == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new BiomeEffects.Particle(
|
||||
probability,
|
||||
Particle.fromKey(particle)
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.dfsek.terra.minestom.config;
|
||||
|
||||
import com.dfsek.tectonic.api.depth.DepthTracker;
|
||||
import com.dfsek.tectonic.api.exception.LoadException;
|
||||
import com.dfsek.tectonic.api.loader.ConfigLoader;
|
||||
import com.dfsek.tectonic.api.loader.type.TypeLoader;
|
||||
import net.kyori.adventure.key.InvalidKeyException;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.intellij.lang.annotations.Subst;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
|
||||
|
||||
public class KeyLoader implements TypeLoader<Key> {
|
||||
@Override
|
||||
public Key load(
|
||||
@NotNull AnnotatedType annotatedType,
|
||||
@NotNull Object o,
|
||||
@NotNull ConfigLoader configLoader,
|
||||
DepthTracker depthTracker
|
||||
) throws LoadException {
|
||||
if(!(o instanceof @Subst("a:o") String stringKey)) {
|
||||
throw new LoadException("Value is not a String", depthTracker);
|
||||
}
|
||||
try {
|
||||
return Key.key(stringKey);
|
||||
} catch(InvalidKeyException e) {
|
||||
throw new LoadException("Can't load key: Invalid Format", e, depthTracker);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.dfsek.terra.minestom.config;
|
||||
|
||||
import com.dfsek.tectonic.api.depth.DepthTracker;
|
||||
import com.dfsek.tectonic.api.exception.LoadException;
|
||||
import com.dfsek.tectonic.api.loader.ConfigLoader;
|
||||
import com.dfsek.tectonic.api.loader.type.TypeLoader;
|
||||
import net.kyori.adventure.key.InvalidKeyException;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.util.RGBLike;
|
||||
import net.minestom.server.color.Color;
|
||||
import org.intellij.lang.annotations.Subst;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
|
||||
|
||||
public class RGBLikeLoader implements TypeLoader<RGBLike> {
|
||||
@Override
|
||||
public RGBLike load(
|
||||
@NotNull AnnotatedType annotatedType,
|
||||
@NotNull Object o,
|
||||
@NotNull ConfigLoader configLoader,
|
||||
DepthTracker depthTracker
|
||||
) throws LoadException {
|
||||
if(!(o instanceof @Subst("a:o") Integer value)) {
|
||||
throw new LoadException("Value is not an integer", depthTracker);
|
||||
}
|
||||
return new Color(value);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.dfsek.terra.minestom.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minestom.server.sound.SoundEvent;
|
||||
|
||||
|
||||
public class SoundEventTemplate implements ObjectTemplate<SoundEvent> {
|
||||
@Value("id")
|
||||
@Default
|
||||
private Key id = null;
|
||||
|
||||
@Value("distance-to-travel")
|
||||
@Default
|
||||
private Float distanceToTravel = null;
|
||||
|
||||
@Override
|
||||
public SoundEvent get() {
|
||||
if(id == null) {
|
||||
return null;
|
||||
} else {
|
||||
// distanceToTravel is specifically allowed to be null.
|
||||
return SoundEvent.of(id, distanceToTravel);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
package com.dfsek.terra.minestom.config;
|
||||
|
||||
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 com.dfsek.terra.api.properties.Properties;
|
||||
|
||||
import net.kyori.adventure.util.RGBLike;
|
||||
import net.minestom.server.sound.SoundEvent;
|
||||
import net.minestom.server.world.biome.Biome.TemperatureModifier;
|
||||
import net.minestom.server.world.biome.BiomeEffects;
|
||||
import net.minestom.server.world.biome.BiomeEffects.GrassColorModifier;
|
||||
|
||||
|
||||
public class VanillaBiomeProperties implements ConfigTemplate, Properties {
|
||||
@Value("colors.grass")
|
||||
@Default
|
||||
private RGBLike grassColor = null;
|
||||
|
||||
@Value("colors.fog")
|
||||
@Default
|
||||
private RGBLike fogColor = null;
|
||||
|
||||
@Value("colors.water")
|
||||
@Default
|
||||
private RGBLike waterColor = null;
|
||||
|
||||
@Value("colors.water-fog")
|
||||
@Default
|
||||
private RGBLike waterFogColor = null;
|
||||
|
||||
@Value("colors.foliage")
|
||||
@Default
|
||||
private RGBLike foliageColor = null;
|
||||
|
||||
@Value("colors.sky")
|
||||
@Default
|
||||
private RGBLike skyColor = null;
|
||||
|
||||
@Value("colors.modifier")
|
||||
@Default
|
||||
private GrassColorModifier grassColorModifier = null;
|
||||
|
||||
@Value("particles")
|
||||
@Default
|
||||
private BiomeEffects.Particle particleConfig = null;
|
||||
|
||||
@Value("climate.precipitation")
|
||||
@Default
|
||||
private Boolean precipitation = null;
|
||||
|
||||
@Value("climate.temperature")
|
||||
@Default
|
||||
private Float temperature = null;
|
||||
|
||||
@Value("climate.temperature-modifier")
|
||||
@Default
|
||||
private TemperatureModifier temperatureModifier = null;
|
||||
|
||||
@Value("climate.downfall")
|
||||
@Default
|
||||
private Float downfall = null;
|
||||
|
||||
@Value("sound.loop-sound.sound")
|
||||
@Default
|
||||
private SoundEvent loopSound = null;
|
||||
|
||||
@Value("sound.mood-sound")
|
||||
@Default
|
||||
private BiomeEffects.MoodSound moodSound = null;
|
||||
|
||||
@Value("sound.additions-sound")
|
||||
@Default
|
||||
private BiomeEffects.AdditionsSound additionsSound = null;
|
||||
|
||||
// @Value("sound.music")
|
||||
// @Default
|
||||
// private MusicSound music = null;
|
||||
|
||||
public RGBLike getGrassColor() {
|
||||
return grassColor;
|
||||
}
|
||||
|
||||
public RGBLike getFogColor() {
|
||||
return fogColor;
|
||||
}
|
||||
|
||||
public RGBLike getWaterColor() {
|
||||
return waterColor;
|
||||
}
|
||||
|
||||
public RGBLike getWaterFogColor() {
|
||||
return waterFogColor;
|
||||
}
|
||||
|
||||
public RGBLike getFoliageColor() {
|
||||
return foliageColor;
|
||||
}
|
||||
|
||||
public RGBLike getSkyColor() {
|
||||
return skyColor;
|
||||
}
|
||||
|
||||
public GrassColorModifier getGrassColorModifier() {
|
||||
return grassColorModifier;
|
||||
}
|
||||
|
||||
public BiomeEffects.Particle getParticleConfig() {
|
||||
return particleConfig;
|
||||
}
|
||||
|
||||
public Boolean getPrecipitation() {
|
||||
return precipitation;
|
||||
}
|
||||
|
||||
public Float getTemperature() {
|
||||
return temperature;
|
||||
}
|
||||
|
||||
public TemperatureModifier getTemperatureModifier() {
|
||||
return temperatureModifier;
|
||||
}
|
||||
|
||||
public Float getDownfall() {
|
||||
return downfall;
|
||||
}
|
||||
|
||||
public SoundEvent getLoopSound() {
|
||||
return loopSound;
|
||||
}
|
||||
|
||||
public BiomeEffects.MoodSound getMoodSound() {
|
||||
return moodSound;
|
||||
}
|
||||
|
||||
public BiomeEffects.AdditionsSound getAdditionsSound() {
|
||||
return additionsSound;
|
||||
}
|
||||
}
|
@ -1,18 +1,16 @@
|
||||
package com.dfsek.terra.minestom.entity;
|
||||
|
||||
|
||||
import net.minestom.server.entity.EntityType;
|
||||
|
||||
|
||||
public class MinestomEntityType implements com.dfsek.terra.api.entity.EntityType {
|
||||
private final EntityType delegate;
|
||||
|
||||
public MinestomEntityType(String id) {
|
||||
delegate = EntityType.fromNamespaceId(id);
|
||||
delegate = EntityType.fromKey(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,9 +3,10 @@ package com.dfsek.terra.minestom.item;
|
||||
import com.dfsek.terra.api.inventory.ItemStack;
|
||||
import com.dfsek.terra.api.inventory.item.Enchantment;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.item.Material;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import net.minestom.server.registry.DynamicRegistry;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@ -16,11 +17,13 @@ public class MinestomEnchantment implements Enchantment {
|
||||
|
||||
public MinestomEnchantment(net.minestom.server.item.enchant.Enchantment delegate) {
|
||||
this.delegate = delegate;
|
||||
id = Objects.requireNonNull(delegate.registry()).raw();
|
||||
DynamicRegistry<net.minestom.server.item.enchant.Enchantment> registry = MinecraftServer.getEnchantmentRegistry();
|
||||
this.id = Objects.requireNonNull(registry.getKey(delegate)).toString();
|
||||
}
|
||||
|
||||
public MinestomEnchantment(String id) {
|
||||
this.delegate = MinecraftServer.getEnchantmentRegistry().get(NamespaceID.from(id));
|
||||
Key key = Key.key(id);
|
||||
this.delegate = MinecraftServer.getEnchantmentRegistry().get(key);
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@ -31,7 +34,19 @@ public class MinestomEnchantment implements Enchantment {
|
||||
|
||||
@Override
|
||||
public boolean conflictsWith(Enchantment other) {
|
||||
return delegate.exclusiveSet().contains(NamespaceID.from(((MinestomEnchantment) other).id));
|
||||
var otherDelegate = ((MinestomEnchantment) other).delegate;
|
||||
delegate.exclusiveSet();
|
||||
|
||||
// Get the registry key for the other enchantment to use in contains
|
||||
try {
|
||||
DynamicRegistry<net.minestom.server.item.enchant.Enchantment> registry = MinecraftServer.getEnchantmentRegistry();
|
||||
DynamicRegistry.Key<net.minestom.server.item.enchant.Enchantment> otherKey = registry.getKey(otherDelegate);
|
||||
return delegate.exclusiveSet().contains(otherKey);
|
||||
} catch (Exception e) {
|
||||
// If the key approach fails, fall back to a more basic implementation
|
||||
String otherId = ((MinestomEnchantment) other).id;
|
||||
return otherId.equals(this.id);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -48,4 +63,4 @@ public class MinestomEnchantment implements Enchantment {
|
||||
public net.minestom.server.item.enchant.Enchantment getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ import com.dfsek.terra.api.inventory.item.Enchantment;
|
||||
import com.dfsek.terra.api.inventory.item.ItemMeta;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.item.ItemComponent;
|
||||
import net.minestom.server.component.DataComponents;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.component.EnchantmentList;
|
||||
import net.minestom.server.registry.DynamicRegistry;
|
||||
@ -47,7 +47,7 @@ public class MinestomItemStack implements com.dfsek.terra.api.inventory.ItemStac
|
||||
@Override
|
||||
public ItemMeta getItemMeta() {
|
||||
HashMap<Enchantment, Integer> enchantments = new HashMap<>();
|
||||
EnchantmentList enchantmentList = base.get(ItemComponent.ENCHANTMENTS);
|
||||
EnchantmentList enchantmentList = base.get(DataComponents.ENCHANTMENTS);
|
||||
if(enchantmentList != null) {
|
||||
enchantmentList.enchantments().forEach((enchantmentKey, integer) -> {
|
||||
enchantments.put(
|
||||
@ -67,6 +67,6 @@ public class MinestomItemStack implements com.dfsek.terra.api.inventory.ItemStac
|
||||
});
|
||||
|
||||
EnchantmentList list = new EnchantmentList(enchantments);
|
||||
base = base.with(ItemComponent.ENCHANTMENTS, list);
|
||||
base = base.with(DataComponents.ENCHANTMENTS, list);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import com.dfsek.terra.api.inventory.ItemStack;
|
||||
|
||||
import net.minestom.server.item.Material;
|
||||
|
||||
|
||||
public class MinestomMaterial implements Item {
|
||||
private final Material delegate;
|
||||
|
||||
@ -14,7 +13,7 @@ public class MinestomMaterial implements Item {
|
||||
}
|
||||
|
||||
public MinestomMaterial(String id) {
|
||||
this.delegate = Material.fromNamespaceId(id);
|
||||
this.delegate = Material.fromId(Integer.parseInt(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -31,4 +30,4 @@ public class MinestomMaterial implements Item {
|
||||
public Material getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +1,23 @@
|
||||
package com.dfsek.terra.minestom.world;
|
||||
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
||||
|
||||
import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
|
||||
import com.dfsek.terra.api.world.chunk.generation.util.GeneratorWrapper;
|
||||
import com.dfsek.terra.minestom.biome.MinestomUserDefinedBiomePool;
|
||||
import com.dfsek.terra.minestom.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.minestom.chunk.CachedChunk;
|
||||
import com.dfsek.terra.minestom.chunk.GeneratedChunkCache;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.instance.generator.GenerationUnit;
|
||||
import net.minestom.server.instance.generator.Generator;
|
||||
import net.minestom.server.instance.generator.UnitModifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
@ -18,13 +25,27 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe
|
||||
private final GeneratedChunkCache cache;
|
||||
private ChunkGenerator generator;
|
||||
private final TerraMinestomWorld world;
|
||||
private final BiomeProvider biomeProvider;
|
||||
private final boolean doFineGrainedBiomes;
|
||||
private ConfigPack pack;
|
||||
private final MinestomUserDefinedBiomePool biomePool;
|
||||
|
||||
public MinestomChunkGeneratorWrapper(ChunkGenerator generator, TerraMinestomWorld world, ConfigPack pack) {
|
||||
public MinestomChunkGeneratorWrapper(
|
||||
Platform platform,
|
||||
ChunkGenerator generator,
|
||||
TerraMinestomWorld world,
|
||||
ConfigPack pack,
|
||||
MinestomUserDefinedBiomePool biomePool,
|
||||
boolean doFineGrainedBiomes
|
||||
) {
|
||||
this.generator = generator;
|
||||
this.world = world;
|
||||
this.pack = pack;
|
||||
this.cache = new GeneratedChunkCache(world.getDimensionType(), generator, world);
|
||||
this.biomePool = biomePool;
|
||||
this.biomeProvider = pack.getBiomeProvider();
|
||||
this.doFineGrainedBiomes = doFineGrainedBiomes;
|
||||
this.cache = new GeneratedChunkCache(world.getDimensionType(), generator, world, biomeProvider);
|
||||
preloadBiomes();
|
||||
}
|
||||
|
||||
public ChunkGenerator getGenerator() {
|
||||
@ -36,8 +57,30 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe
|
||||
Point start = unit.absoluteStart();
|
||||
int x = start.chunkX();
|
||||
int z = start.chunkZ();
|
||||
int blockX = start.blockX();
|
||||
int blockZ = start.blockZ();
|
||||
int minY = world.getMinHeight();
|
||||
int maxY = world.getMaxHeight();
|
||||
CachedChunk chunk = cache.at(x, z);
|
||||
chunk.writeRelative(unit.modifier());
|
||||
UnitModifier modifier = unit.modifier();
|
||||
chunk.writeRelative(modifier);
|
||||
|
||||
if(doFineGrainedBiomes) {
|
||||
for(int y = minY; y < maxY; y++) {
|
||||
for(int absoluteX = blockX; absoluteX < blockX + 16; absoluteX++) {
|
||||
for(int absoluteZ = blockZ; absoluteZ < blockZ + 16; absoluteZ++) {
|
||||
UserDefinedBiome userDefinedBiome = biomePool.getBiome(
|
||||
biomeProvider.getBiome(absoluteX, y, absoluteZ, world.getSeed())
|
||||
);
|
||||
modifier.setBiome(absoluteX, y, absoluteZ, userDefinedBiome.registry());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// TODO: remove with feature flag once minestom fixed biome encoding
|
||||
UserDefinedBiome userDefinedBiome = biomePool.getBiome(biomeProvider.getBiome(blockX, 100, blockZ, world.getSeed()));
|
||||
modifier.fillBiome(userDefinedBiome.registry());
|
||||
}
|
||||
|
||||
unit.fork(setter -> {
|
||||
MinestomProtoWorld protoWorld = new MinestomProtoWorld(cache, x, z, world, setter);
|
||||
@ -55,6 +98,15 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe
|
||||
public void setPack(ConfigPack pack) {
|
||||
this.pack = pack;
|
||||
this.generator = pack.getGeneratorProvider().newInstance(pack);
|
||||
this.biomePool.invalidate();
|
||||
preloadBiomes();
|
||||
}
|
||||
|
||||
private void preloadBiomes() {
|
||||
this.biomePool.preloadBiomes(world.getBiomeProvider().getBiomes());
|
||||
for(Player player : MinecraftServer.getConnectionManager().getOnlinePlayers()) {
|
||||
player.startConfigurationPhase();
|
||||
}
|
||||
}
|
||||
|
||||
public void displayStats() {
|
||||
|
@ -5,6 +5,7 @@ import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.entity.Entity;
|
||||
import com.dfsek.terra.api.entity.EntityType;
|
||||
import com.dfsek.terra.api.util.generic.pair.Pair;
|
||||
import com.dfsek.terra.api.world.ServerWorld;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
||||
@ -17,6 +18,11 @@ import com.dfsek.terra.minestom.entity.DeferredMinestomEntity;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.Block.Setter;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
|
||||
public class MinestomProtoWorld implements ProtoWorld {
|
||||
private final GeneratedChunkCache cache;
|
||||
@ -51,6 +57,10 @@ public class MinestomProtoWorld implements ProtoWorld {
|
||||
@Override
|
||||
public void setBlockState(int x, int y, int z, BlockState data, boolean physics) {
|
||||
modifier.setBlock(x, y, z, (Block) data.getHandle());
|
||||
int chunkX = x >> 4;
|
||||
int chunkZ = z >> 4;
|
||||
CachedChunk chunk = cache.at(chunkX, chunkZ);
|
||||
chunk.setBlock(x & 15, y, z & 15, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -13,8 +13,12 @@ import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
||||
|
||||
import com.dfsek.terra.api.world.info.WorldProperties;
|
||||
|
||||
import com.dfsek.terra.minestom.TerraMinestomPlatform;
|
||||
import com.dfsek.terra.minestom.api.BlockEntityFactory;
|
||||
import com.dfsek.terra.minestom.api.EntityFactory;
|
||||
import com.dfsek.terra.minestom.api.BiomeFactory;
|
||||
import com.dfsek.terra.minestom.biome.MinestomUserDefinedBiomeFactory;
|
||||
import com.dfsek.terra.minestom.biome.MinestomUserDefinedBiomePool;
|
||||
import com.dfsek.terra.minestom.block.MinestomBlockState;
|
||||
import com.dfsek.terra.minestom.entity.MinestomEntity;
|
||||
|
||||
@ -37,8 +41,16 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties {
|
||||
private final EntityFactory entityFactory;
|
||||
private final BlockEntityFactory blockEntityFactory;
|
||||
|
||||
public TerraMinestomWorld(Instance instance, ConfigPack pack, long seed, EntityFactory entityFactory,
|
||||
BlockEntityFactory blockEntityFactory) {
|
||||
public TerraMinestomWorld(
|
||||
TerraMinestomPlatform platform,
|
||||
Instance instance,
|
||||
ConfigPack pack,
|
||||
long seed,
|
||||
EntityFactory entityFactory,
|
||||
BlockEntityFactory blockEntityFactory,
|
||||
BiomeFactory factory,
|
||||
boolean doFineGrainedBiomes
|
||||
) {
|
||||
this.instance = instance;
|
||||
this.pack = pack;
|
||||
this.seed = seed;
|
||||
@ -46,7 +58,14 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties {
|
||||
this.dimensionType = MinecraftServer.getDimensionTypeRegistry().get(instance.getDimensionType());
|
||||
this.blockEntityFactory = blockEntityFactory;
|
||||
|
||||
this.wrapper = new MinestomChunkGeneratorWrapper(pack.getGeneratorProvider().newInstance(pack), this, pack);
|
||||
this.wrapper = new MinestomChunkGeneratorWrapper(
|
||||
platform,
|
||||
pack.getGeneratorProvider().newInstance(pack),
|
||||
this,
|
||||
pack,
|
||||
new MinestomUserDefinedBiomePool(pack, factory),
|
||||
doFineGrainedBiomes
|
||||
);
|
||||
this.entityFactory = entityFactory;
|
||||
|
||||
instance.setGenerator(this.wrapper);
|
||||
|
@ -1,75 +0,0 @@
|
||||
package com.dfsek.terra.minestom.world;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
|
||||
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||
|
||||
import com.dfsek.terra.minestom.MinestomPlatform;
|
||||
import com.dfsek.terra.minestom.api.BlockEntityFactory;
|
||||
import com.dfsek.terra.minestom.api.EntityFactory;
|
||||
import com.dfsek.terra.minestom.block.DefaultBlockEntityFactory;
|
||||
import com.dfsek.terra.minestom.entity.DefaultEntityFactory;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.instance.Instance;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
||||
public class TerraMinestomWorldBuilder {
|
||||
private final Instance instance;
|
||||
private ConfigPack pack;
|
||||
private long seed = new Random().nextLong();
|
||||
private EntityFactory entityFactory = new DefaultEntityFactory();
|
||||
private BlockEntityFactory blockEntityFactory = new DefaultBlockEntityFactory();
|
||||
|
||||
private TerraMinestomWorldBuilder(Instance instance) { this.instance = instance; }
|
||||
|
||||
public static TerraMinestomWorldBuilder from(Instance instance) {
|
||||
return new TerraMinestomWorldBuilder(instance);
|
||||
}
|
||||
|
||||
public static TerraMinestomWorldBuilder builder() {
|
||||
return new TerraMinestomWorldBuilder(MinecraftServer.getInstanceManager().createInstanceContainer());
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder pack(ConfigPack pack) {
|
||||
this.pack = pack;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder packById(String id) {
|
||||
this.pack = MinestomPlatform.getInstance().getConfigRegistry().getByID(id).orElseThrow();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder findPack(Function<CheckedRegistry<ConfigPack>, ConfigPack> fn) {
|
||||
this.pack = fn.apply(MinestomPlatform.getInstance().getConfigRegistry());
|
||||
return this;
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder defaultPack() {
|
||||
return this.packById("OVERWORLD");
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder seed(long seed) {
|
||||
this.seed = seed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder entityFactory(EntityFactory factory) {
|
||||
this.entityFactory = factory;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TerraMinestomWorldBuilder blockEntityFactory(BlockEntityFactory factory) {
|
||||
this.blockEntityFactory = factory;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TerraMinestomWorld attach() {
|
||||
return new TerraMinestomWorld(instance, pack, seed, entityFactory, blockEntityFactory);
|
||||
}
|
||||
}
|
@ -44,7 +44,7 @@ import com.dfsek.terra.mod.config.MusicSoundTemplate;
|
||||
import com.dfsek.terra.mod.config.ProtoPlatformBiome;
|
||||
import com.dfsek.terra.mod.config.SoundEventTemplate;
|
||||
import com.dfsek.terra.mod.config.SpawnCostConfig;
|
||||
import com.dfsek.terra.mod.config.SpawnEntryTemplate;
|
||||
import com.dfsek.terra.mod.config.SpawnEntryConfig;
|
||||
import com.dfsek.terra.mod.config.SpawnSettingsTemplate;
|
||||
import com.dfsek.terra.mod.config.SpawnTypeConfig;
|
||||
import com.dfsek.terra.mod.config.VillagerTypeTemplate;
|
||||
@ -94,7 +94,7 @@ public abstract class ModPlatform extends AbstractPlatform {
|
||||
.registerLoader(MusicSound.class, MusicSoundTemplate::new)
|
||||
.registerLoader(EntityType.class, EntityTypeTemplate::new)
|
||||
.registerLoader(SpawnCostConfig.class, SpawnCostConfig::new)
|
||||
.registerLoader(SpawnEntry.class, SpawnEntryTemplate::new)
|
||||
.registerLoader(SpawnEntry.class, SpawnEntryConfig::new)
|
||||
.registerLoader(SpawnTypeConfig.class, SpawnTypeConfig::new)
|
||||
.registerLoader(SpawnSettings.class, SpawnSettingsTemplate::new)
|
||||
.registerLoader(VillagerType.class, VillagerTypeTemplate::new);
|
||||
|
@ -8,8 +8,7 @@ import net.minecraft.world.biome.SpawnSettings.SpawnEntry;
|
||||
|
||||
import com.dfsek.terra.api.util.range.Range;
|
||||
|
||||
|
||||
public class SpawnEntryTemplate implements ObjectTemplate<SpawnEntry> {
|
||||
public class SpawnEntryConfig implements ObjectTemplate<SpawnEntry> {
|
||||
@Value("type")
|
||||
@Default
|
||||
private EntityType<?> type = null;
|
||||
@ -22,8 +21,12 @@ public class SpawnEntryTemplate implements ObjectTemplate<SpawnEntry> {
|
||||
@Default
|
||||
private Range groupSize = null;
|
||||
|
||||
public Integer getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpawnEntry get() {
|
||||
return new SpawnEntry(type, weight, groupSize.getMin(), groupSize.getMax());
|
||||
return new SpawnEntry(type, groupSize.getMin(), groupSize.getMax());
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minecraft.entity.SpawnGroup;
|
||||
import net.minecraft.world.biome.SpawnSettings;
|
||||
import net.minecraft.world.biome.SpawnSettings.SpawnEntry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -28,8 +27,8 @@ public class SpawnSettingsTemplate implements ObjectTemplate<SpawnSettings> {
|
||||
SpawnSettings.Builder builder = new SpawnSettings.Builder();
|
||||
for(SpawnTypeConfig spawn : spawns) {
|
||||
SpawnGroup group = spawn.getGroup();
|
||||
for(SpawnEntry entry : spawn.getEntry()) {
|
||||
builder.spawn(group, entry);
|
||||
for(SpawnEntryConfig entry : spawn.getEntry()) {
|
||||
builder.spawn(group, entry.getWeight(), entry.get());
|
||||
}
|
||||
}
|
||||
for(SpawnCostConfig cost : costs) {
|
||||
|
@ -4,7 +4,6 @@ import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minecraft.entity.SpawnGroup;
|
||||
import net.minecraft.world.biome.SpawnSettings.SpawnEntry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -16,13 +15,13 @@ public class SpawnTypeConfig implements ObjectTemplate<SpawnTypeConfig> {
|
||||
|
||||
@Value("entries")
|
||||
@Default
|
||||
private List<SpawnEntry> entry = null;
|
||||
private List<SpawnEntryConfig> entry = null;
|
||||
|
||||
public SpawnGroup getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public List<SpawnEntry> getEntry() {
|
||||
public List<SpawnEntryConfig> getEntry() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package com.dfsek.terra.mod.config;
|
||||
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.registry.RegistryKey;
|
||||
import net.minecraft.sound.BiomeAdditionsSound;
|
||||
import net.minecraft.sound.BiomeMoodSound;
|
||||
import net.minecraft.sound.MusicSound;
|
||||
@ -87,7 +88,8 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
|
||||
|
||||
@Value("villager-type")
|
||||
@Default
|
||||
private VillagerType villagerType = null;
|
||||
private
|
||||
RegistryKey<VillagerType> villagerType = null;
|
||||
|
||||
public Integer getGrassColor() {
|
||||
return grassColor;
|
||||
@ -157,7 +159,7 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
|
||||
return spawnSettings;
|
||||
}
|
||||
|
||||
public VillagerType getVillagerType() {
|
||||
public RegistryKey<VillagerType> getVillagerType() {
|
||||
return villagerType;
|
||||
}
|
||||
}
|
||||
|
@ -4,17 +4,19 @@ import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.village.VillagerType;
|
||||
|
||||
|
||||
public class VillagerTypeTemplate implements ObjectTemplate<VillagerType> {
|
||||
public class VillagerTypeTemplate implements ObjectTemplate<RegistryKey<VillagerType>> {
|
||||
@Value("id")
|
||||
@Default
|
||||
private Identifier id = null;
|
||||
private String id = null;
|
||||
|
||||
@Override
|
||||
public VillagerType get() {
|
||||
return Registries.VILLAGER_TYPE.getEntry(id).orElseThrow().value();
|
||||
public RegistryKey<VillagerType> get() {
|
||||
return RegistryKey.of(RegistryKeys.VILLAGER_TYPE, Identifier.ofVanilla(id));
|
||||
}
|
||||
}
|
||||
|
@ -135,10 +135,10 @@ public class MinecraftChunkGeneratorWrapper extends net.minecraft.world.gen.chun
|
||||
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);
|
||||
.get(depth, x + xi, y, z + zi, world.getSeed()), 0);
|
||||
depth++;
|
||||
} else if(noise < airThreshold) {
|
||||
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.getDefaultState(), false);
|
||||
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.getDefaultState(), 0);
|
||||
} else {
|
||||
depth = 0;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import java.util.Map;
|
||||
@Mixin(VillagerType.class)
|
||||
public interface VillagerTypeAccessor {
|
||||
@Accessor("BIOME_TO_TYPE")
|
||||
static Map<RegistryKey<Biome>, VillagerType> getBiomeTypeToIdMap() {
|
||||
static Map<RegistryKey<Biome>, RegistryKey<VillagerType>> getBiomeTypeToIdMap() {
|
||||
throw new AssertionError("Untransformed Accessor!");
|
||||
}
|
||||
}
|
||||
|
@ -45,18 +45,4 @@ public abstract class ServerWorldMixin extends World {
|
||||
}
|
||||
return instance.matchesKey(tRegistryKey);
|
||||
}
|
||||
|
||||
@Redirect(method = "<init>",
|
||||
at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/village/raid/RaidManager;nameFor(Lnet/minecraft/registry/entry/RegistryEntry;)" +
|
||||
"Ljava/lang/String;"))
|
||||
public String nameForProxy(RegistryEntry<DimensionType> dimensionTypeEntry) {
|
||||
RegistryEntry<DimensionType> entry = dimensionTypeEntry;
|
||||
if(this.getRegistryKey() == World.END) {
|
||||
Registry<DimensionType> dimensionTypeRegistry = getRegistryManager().getOrThrow(RegistryKeys.DIMENSION_TYPE);
|
||||
entry = dimensionTypeRegistry.getEntry(dimensionTypeRegistry.get(DimensionTypes.THE_NETHER));
|
||||
|
||||
}
|
||||
return RaidManager.nameFor(entry);
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public abstract class MobSpawnerBlockEntityMixin extends BlockEntity {
|
||||
|
||||
public EntityType terra$getSpawnedType() {
|
||||
return (EntityType) Registries.ENTITY_TYPE.getEntry(
|
||||
Identifier.tryParse(((MobSpawnerLogicAccessor) getLogic()).getSpawnEntry().getNbt().getString("id"))).orElseThrow();
|
||||
Identifier.tryParse(((MobSpawnerLogicAccessor) getLogic()).getSpawnEntry().getNbt().getString("id").orElseThrow())).orElseThrow();
|
||||
}
|
||||
|
||||
public void terra$setSpawnedType(@NotNull EntityType creatureType) {
|
||||
|
@ -47,11 +47,11 @@ public abstract class WorldChunkMixin {
|
||||
|
||||
@Shadow
|
||||
@Nullable
|
||||
public abstract net.minecraft.block.BlockState setBlockState(BlockPos pos, net.minecraft.block.BlockState state, boolean moved);
|
||||
public abstract net.minecraft.block.BlockState setBlockState(BlockPos pos, net.minecraft.block.BlockState state, int flags);
|
||||
|
||||
public void terra$setBlock(int x, int y, int z, BlockState data, boolean physics) {
|
||||
BlockPos blockPos = new BlockPos(x, y, z);
|
||||
setBlockState(blockPos, (net.minecraft.block.BlockState) data, false);
|
||||
setBlockState(blockPos, (net.minecraft.block.BlockState) data, 0);
|
||||
if(physics) {
|
||||
net.minecraft.block.BlockState state = ((net.minecraft.block.BlockState) data);
|
||||
if(state.isLiquid()) {
|
||||
@ -65,7 +65,7 @@ public abstract class WorldChunkMixin {
|
||||
|
||||
public void terra$setBlock(int x, int y, int z, @NotNull BlockState blockState) {
|
||||
((net.minecraft.world.chunk.Chunk) (Object) this).setBlockState(new BlockPos(x, y, z), (net.minecraft.block.BlockState) blockState,
|
||||
false);
|
||||
0);
|
||||
}
|
||||
|
||||
@Intrinsic
|
||||
|
@ -40,7 +40,7 @@ public abstract class ProtoChunkMixin {
|
||||
|
||||
public void terra$setBlock(int x, int y, int z, @NotNull BlockState blockState) {
|
||||
((net.minecraft.world.chunk.Chunk) (Object) this).setBlockState(new BlockPos(x, y, z), (net.minecraft.block.BlockState) blockState,
|
||||
false);
|
||||
0);
|
||||
}
|
||||
|
||||
public @NotNull BlockState terra$getBlock(int x, int y, int z) {
|
||||
|
@ -51,13 +51,35 @@ public final class LifecycleBiomeUtil {
|
||||
Registry<net.minecraft.world.biome.Biome> registry) {
|
||||
RegistryKey<net.minecraft.world.biome.Biome> vanilla = ((ProtoPlatformBiome) biome.getPlatformBiome()).get(registry);
|
||||
|
||||
if (vanilla == null) {
|
||||
logger.error("""
|
||||
Failed to get Vanilla Biome Regiestry key!
|
||||
Terra Biome ID: {}
|
||||
Vanilla Biome: {}""", biome.getID(), biome.getPlatformBiome());
|
||||
}
|
||||
|
||||
if(pack.getContext().get(PreLoadCompatibilityOptions.class).useVanillaBiomes()) {
|
||||
((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(registry.getEntry(registry.get(vanilla)));
|
||||
} else {
|
||||
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
||||
|
||||
net.minecraft.world.biome.Biome minecraftBiome = BiomeUtil.createBiome(Objects.requireNonNull(registry.get(vanilla)),
|
||||
|
||||
net.minecraft.world.biome.Biome vanilaBiome = registry.get(vanilla);
|
||||
if (vanilaBiome == null) {
|
||||
String vanillaBiomeName;
|
||||
if (vanilla != null ) {
|
||||
vanillaBiomeName = vanilla.getValue().toString();
|
||||
} else {
|
||||
vanillaBiomeName = "NULL";
|
||||
}
|
||||
logger.error("""
|
||||
Failed to get Vanilla Biome!
|
||||
Terra Biome ID: {}
|
||||
Vanilla Biome: {}""", biome.getID(), vanillaBiomeName);
|
||||
return;
|
||||
}
|
||||
|
||||
net.minecraft.world.biome.Biome minecraftBiome = BiomeUtil.createBiome(Objects.requireNonNull(vanilaBiome),
|
||||
vanillaBiomeProperties);
|
||||
|
||||
Identifier identifier = Identifier.of("terra", BiomeUtil.createBiomeID(pack, id));
|
||||
@ -72,7 +94,7 @@ public final class LifecycleBiomeUtil {
|
||||
minecraftBiome));
|
||||
}
|
||||
|
||||
Map<RegistryKey<net.minecraft.world.biome.Biome>, VillagerType> villagerMap = VillagerTypeAccessor.getBiomeTypeToIdMap();
|
||||
Map<RegistryKey<net.minecraft.world.biome.Biome>, RegistryKey<VillagerType>> villagerMap = VillagerTypeAccessor.getBiomeTypeToIdMap();
|
||||
|
||||
villagerMap.put(RegistryKey.of(RegistryKeys.BIOME, identifier),
|
||||
Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user