Compare commits

..

67 Commits

Author SHA1 Message Date
Oak 2b62473372 Update Versions.kt 2025-07-17 14:13:40 +01:00
Zoë Gidiere 9f546370cd Merge pull request #519 from PolyhedralDev/feat/nmsplatform
Fixed NMSPlatform implementation
2025-07-13 16:44:10 -06:00
Zoë Gidiere 428bf341ef Better handling of internal addon 2025-07-13 15:47:48 -06:00
OakLoaf 8a61571ceb Fixed biome registering 2025-07-13 14:48:56 +01:00
OakLoaf b669f87b79 Merge branch 'refs/heads/master' into feat/nmsplatform 2025-07-13 14:22:00 +01:00
OakLoaf e507675ef6 Removed unused import 2025-07-13 14:21:45 +01:00
Zoë Gidiere 3322a16f09 Fix particle releated crash on bukkit 2025-07-10 19:50:54 -06:00
Zoë Gidiere c658d1a81b Merge remote-tracking branch 'origin/master' 2025-07-10 19:42:38 -06:00
Zoë Gidiere 56a7234494 Merge pull request #518 from PolyhedralDev/feat/nmsplatform
Implemented vanilla biome config options
2025-07-10 19:40:22 -06:00
Zoë Gidiere 217b708177 Update NMSPlatform.java 2025-07-10 19:40:05 -06:00
OakLoaf 7d86a41f65 Updates to particles 2025-07-10 11:29:31 +01:00
OakLoaf 753574fc9b Implemented vanilla biome config options 2025-07-10 11:14:22 +01:00
Zoë Gidiere 95f89ed2b6 reformat tesf test 2025-07-09 21:59:13 -06:00
Zoë Gidiere cb8aefe8d2 updates to particles 2025-07-09 19:31:48 -06:00
Zoë Gidiere 79f9488380 Merge pull request #515 from PolyhedralDev/dev/1.21.7
Bumped Cloud for Paper and Fabric version
2025-07-09 16:42:23 -06:00
Zoë Gidiere 4c2ce65cdc Some fixes to biome config 2025-07-09 16:41:53 -06:00
Zoë Gidiere 70c448dd0d Fix particles 2025-07-09 15:06:40 -06:00
OakLoaf 060bda2ec1 Bumped cloud-fabric version 2025-07-03 18:21:41 +01:00
Zoë Gidiere 6b60246694 Merge pull request #514 from PolyhedralDev/dev/1.21.7
Update to 1.21.7
2025-06-30 11:13:24 -06:00
OakLoaf 1a1f461550 Corrected version in fabric.mod.json 2025-06-30 17:57:19 +01:00
OakLoaf da20e282ce Updated Fabric to 1.21.7 2025-06-30 17:53:50 +01:00
OakLoaf 9b14b0ee96 Updated Bukkit to 1.21.7 2025-06-30 16:47:29 +01:00
Zoë Gidiere 118aeb872f Merge pull request #511 from PolyhedralDev/dev/wolves
Fixed wolf variant support for Paper platform
2025-06-23 13:17:18 -06:00
OakLoaf 5446b729f9 Finalised wolves 2025-06-19 21:44:24 +01:00
Oak d71c6bb25f Corrected checks 2025-06-19 21:22:06 +01:00
Oak d8524603c6 Implemented wolf variant support 2025-06-19 21:12:24 +01:00
OakLoaf 85234ddc39 Progress on wolves 2025-06-19 20:50:31 +01:00
OakLoaf 78162eaafe Added vanilla biome key to biome context 2025-06-19 20:49:57 +01:00
OakLoaf 7a041d8a63 Removed unused import 2025-06-19 20:49:37 +01:00
Zoë Gidiere 8cfa2e1467 bump version 2025-06-19 12:23:59 -06:00
Zoë Gidiere 5f367c0f2c Merge pull request #510 from PolyhedralDev/dev/multiverse-fix
Fixed issues causing plugin to fail to load if Multiverse is not present
2025-06-19 12:00:07 -06:00
OakLoaf f4db7fc507 Added initial wolf variant support (not functional) 2025-06-19 15:46:46 +01:00
OakLoaf ad9d16f48c Updated biome collection 2025-06-19 15:46:18 +01:00
OakLoaf 85b6dcc891 Moved all code that requires Multiverse imports into MultiverseGeneratorPluginHook 2025-06-19 14:24:04 +01:00
Zoë Gidiere 29691dfb4d Merge pull request #509 from everbuild-org/master
feat: backport latest minestom support from 7.0 branch
2025-06-18 17:49:21 -06:00
Christian Bergschneider 81eab13ce1 feat: backport latest minestom support from 7.0 branch 2025-06-19 01:42:31 +02:00
Zoë Gidiere 68d5b22ca4 bump fabric dep version 2025-06-17 19:08:14 -06:00
Zoë Gidiere 40b8c85c75 Cleanup 2025-06-17 18:50:24 -06:00
Zoë Gidiere 63367e5f03 Final changes 2025-06-17 18:41:09 -06:00
Zoë Gidiere 1d95e7a87d Merge pull request #506 from benwoo1110/feat/multiverse-hook
Implement multiverse generator plugin hook
2025-06-17 16:23:19 -06:00
Zoë Gidiere b2e21d8b70 Merge pull request #508 from PolyhedralDev/dev/1.21.6
Dev/1.21.6
2025-06-17 15:34:38 -06:00
Zoë Gidiere 4041239b03 fix build 2025-06-17 15:28:47 -06:00
Zoë Gidiere 280699bbce Update to 1.21.6 and fix a lot of bugs in fabric impl 2025-06-17 15:21:21 -06:00
Zoë Gidiere 6984dc29d0 Fix fabric 2025-06-14 00:45:32 -06:00
Zoë Gidiere bd253ea5d2 Merge branch 'master' into dev/1.21.6 2025-06-13 22:08:53 -06:00
OakLoaf d743d7d1df Updated fabric to rc1 2025-06-13 22:50:55 +01:00
OakLoaf 238a7954a7 Added paperweight to bukkit platform for runDevBundleServer task 2025-06-13 21:56:54 +01:00
OakLoaf c2319ca4ab Updated to 1.21.6-rc.1 2025-06-13 20:17:56 +01:00
Ben Woo 95172bfa7e Fix checkstyle for catch 2025-06-13 22:33:41 +08:00
Ben Woo 124dbc8836 Improve error checking for multiverse hook 2025-06-13 19:13:57 +08:00
Zoë Gidiere 8706340584 Fix wolves 2025-06-12 16:25:14 -06:00
OakLoaf 9a9f90aa0d Updated fabric platform to 1.21.6 2025-06-10 12:01:17 +01:00
OakLoaf 20a5bfdd0f Updated bukkit platform to 1.21.6 2025-06-10 11:44:10 +01:00
Ben Woo 4fee8cdb24 More example usages by iterating config pack 2025-06-10 12:06:24 +08:00
Ben Woo 70de38ffcb Fix exception variable name 2025-06-10 12:05:59 +08:00
Ben Woo 6722d22f72 Fix onarandombox repo url 2025-06-10 12:05:46 +08:00
Ben Woo c5526c86a2 Implement multiverse plugin hook 2025-06-09 22:58:41 +08:00
Zoë Gidiere 84fa72f96c Catch all runtime errors when loading packs 2025-06-07 22:14:36 -06:00
Zoë Gidiere cc5258ce73 bump version 2025-06-07 21:12:26 -06:00
Zoë Gidiere 748e027282 Merge pull request #505 from HaHaWTH/master
Identify Moonrise worker threads correctly
2025-06-07 07:18:45 +00:00
HaHaWTH bf6612edd0 Identify Moonrise worker threads correctly 2025-06-07 00:17:51 +14:00
Zoë Gidiere d90a4200fe Update gradle-build.yml 2025-06-05 19:19:43 -06:00
Zoë Gidiere af9fb211a8 bump fabric minecraft dep 2025-06-05 17:50:44 -06:00
Zoë Gidiere e4395cec83 bump version 2025-06-05 17:18:55 -06:00
Zoë Gidiere bab8923f1e update overworld version 2025-06-04 00:21:14 -06:00
Zoë Gidiere b4068e6c59 Merge branch 'dev/1.21.5' 2025-06-03 22:28:48 -06:00
Zoë Gidiere b143c72d0e Dev/1.21.5 (#495)
* Bukkit Build Fix (#494)

* Bukkit Build Fix

* remove comments

* remove papermc repo from gradle settings

* add back gradle shasum

* fix formatting, update gradle hash

* Initial Fabric 1.21.5

* Updated dependencies

* Updated SpawnerData with backwards compat

* Updated dependencies

* Updated setBlockState usage - needs verifying as flags are confusing

* Refactored Bukkit NMS packages

* Initial attempt at updating mixin-commons

* Continue fabric 1.21.5 WIP

* Some additional logging

* Update deps

* Build fixes and update allay

* Add oak to authors

---------

Co-authored-by: Mikal <Ifiht@users.noreply.github.com>
Co-authored-by: OakLoaf <oak@beaconstudios.org>
2025-06-03 22:20:23 -06:00
90 changed files with 885 additions and 321 deletions
+4 -4
View File
@@ -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
+3 -3
View File
@@ -1,8 +1,8 @@
preRelease(true)
versionProjects(":common:api", version("6.6.1"))
versionProjects(":common:implementation", version("6.6.1"))
versionProjects(":platforms", version("6.6.1"))
versionProjects(":common:api", version("6.6.5"))
versionProjects(":common:implementation", version("6.6.5"))
versionProjects(":platforms", version("6.6.5"))
allprojects {
+6
View File
@@ -6,6 +6,12 @@ plugins {
repositories {
mavenCentral()
gradlePluginPortal()
maven("https://maven.solo-studios.ca/releases") {
name = "Solo Studios"
}
maven("https://maven.solo-studios.ca/snapshots") {
name = "Solo Studios"
}
maven("https://repo.codemc.org/repository/maven-public") {
name = "CodeMC"
}
@@ -30,6 +30,12 @@ fun Project.configureDependencies() {
repositories {
mavenCentral()
gradlePluginPortal()
maven("https://maven.solo-studios.ca/releases") {
name = "Solo Studios"
}
maven("https://maven.solo-studios.ca/snapshots") {
name = "Solo Studios"
}
maven("https://maven.fabricmc.net/") {
name = "FabricMC"
}
@@ -60,6 +66,9 @@ fun Project.configureDependencies() {
maven("https://storehouse.okaeri.eu/repository/maven-public/") {
name = "Okaeri"
}
maven("https://repo.onarandombox.com/multiverse-releases") {
name = "onarandombox"
}
}
dependencies {
+14 -12
View File
@@ -1,6 +1,6 @@
object Versions {
object Terra {
const val overworldConfig = "v1.3.4"
const val overworldConfig = "v1.5.2"
}
object Libraries {
@@ -10,7 +10,7 @@ object Versions {
const val cloud = "2.0.0"
const val caffeine = "3.2.0"
const val caffeine = "3.2.1"
const val slf4j = "2.0.17"
@@ -22,14 +22,14 @@ object Versions {
const val asm = "9.8"
const val snakeYml = "2.4"
const val jetBrainsAnnotations = "26.0.2"
const val junit = "5.13.0"
const val junit = "5.13.1"
const val nbt = "6.1"
}
}
object Fabric {
const val fabricAPI = "0.125.3+${Mod.minecraft}"
const val cloud = "2.0.0-beta.10"
const val fabricAPI = "0.128.1+${Mod.minecraft}"
const val cloud = "2.0.0-beta.11"
}
//
// object Quilt {
@@ -39,8 +39,9 @@ object Versions {
object Mod {
const val mixin = "0.15.5+mixin.0.8.7"
const val mixinExtras = "0.4.1"
const val minecraft = "1.21.5"
const val minecraft = "1.21.7"
const val yarn = "$minecraft+build.1"
const val fabricLoader = "0.16.14"
@@ -55,18 +56,19 @@ object Versions {
// }
object Bukkit {
const val minecraft = "1.21.5-R0.1"
const val paperBuild = "$minecraft-20250529.121722-14"
const val minecraft = "1.21.7-R0.1"
const val paperBuild = "$minecraft-20250630.144242-1"
const val paper = paperBuild
const val paperLib = "1.0.8"
const val reflectionRemapper = "0.1.2"
const val paperDevBundle = "$minecraft-20250529.121722-99"
const val paperDevBundle = paperBuild
const val runPaper = "2.3.1"
const val paperWeight = "2.0.0-beta.17"
const val cloud = "2.0.0-beta.10"
const val cloud = "2.0.0-beta.11"
const val multiverse = "5.0.2"
}
//
//
// object Sponge {
// const val sponge = "9.0.0-SNAPSHOT"
// const val mixin = "0.8.2"
@@ -86,6 +88,6 @@ object Versions {
}
object Minestom {
const val minestom = "187931e50b"
const val minestom = "1_21_6-c3ccee696b"
}
}
@@ -1,10 +1,10 @@
bool thing1 = 2 > (2+2) || false;
bool thing1 = 2 > (2 + 2) || false;
if(2 > 2 || 3 + 4 <= 2 && 4 + 5 > 2 / 3) {
if (2 > 2 || 3 + 4 <= 2 && 4 + 5 > 2 / 3) {
test("ok", 2);
}
test("minecraft:green_w" + "ool", (2 * (3+1) * (2 * (1+1))));
test("minecraft:green_w" + "ool", (2 * (3 + 1) * (2 * (1 + 1))));
//
num testVar = 3.4;
@@ -21,7 +21,7 @@ bool iftest = false;
bool truetest = false;
num iterator = 0;
num thing = 4 - 2-2+2-2+2;
num thing = 4 - 2 - 2 + 2 - 2 + 2;
test("4 - 2 = " + thing, 2);
thing = -2;
@@ -31,54 +31,54 @@ test("--2 = " + thing, 2);
for(num i = 0; i < 5; i = i + 1) {
for (num i = 0; i < 5; i = i + 1) {
test("i = " + i, iterator);
if(i > 1 + 1) {
if (i > 1 + 1) {
test("more than 2", iterator);
continue;
}
}
for(num i = 0; i < 5; i = i + 1) {
for (num i = 0; i < 5; i = i + 1) {
test("i = " + i, iterator);
}
for(num j = 0; j < 5; j = j + 1) test("single statement j = " + j, iterator);
for (num j = 0; j < 5; j = j + 1) test("single statement j = " + j, iterator);
if(4 + 2 == 2 + 4) {
if (4 + 2 == 2 + 4) {
test("new thing " + 2, iterator);
}
while(iterator < 5) {
while (iterator < 5) {
test("always, even after " + 2, iterator);
iterator = iterator + 1;
if(iterator > 2) {
if (iterator > 2) {
continue;
}
test("not after " + 2, iterator);
}
if(true) test("single statement" + 2, iterator);
else if(true) test("another single statement" + 2, iterator);
if (true) test("single statement" + 2, iterator);
else if (true) test("another single statement" + 2, iterator);
if(true) {
test("true!" + 2, iterator);
} else {
test("false!" + 2, iterator);
}
if(false) {
if (true) {
test("true!" + 2, iterator);
} else {
test("false!" + 2, iterator);
}
if(false) {
test("true again!" + 2, iterator);
} else if(true == true) {
test("false again!" + 2, iterator);
if (false) {
test("true!" + 2, iterator);
} else {
test("not logged!" + 2, iterator);
test("false!" + 2, iterator);
}
if (false) {
test("true again!" + 2, iterator);
} else if (true == true) {
test("false again!" + 2, iterator);
} else {
test("not logged!" + 2, iterator);
}
@@ -91,7 +91,7 @@ fsdfsd
test("fdsgdf" + 2, 1 + testVar);
if(true && !(boolean && false) && true) {
if (true && !(boolean && false) && true) {
num scopedVar = 2;
test("if statement" + 2 + stringVar, 1 + testVar + scopedVar);
}
@@ -31,6 +31,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -106,7 +108,7 @@ public abstract class AbstractPlatform implements Platform {
return Collections.emptySet();
}
protected void load() {
protected InternalAddon load() {
if(LOADED.get()) {
throw new IllegalStateException(
"Someone tried to initialize Terra, but Terra has already initialized. This is most likely due to a broken platform " +
@@ -157,6 +159,8 @@ public abstract class AbstractPlatform implements Platform {
logger.info("Terra addons successfully loaded.");
logger.info("Finished initialization.");
return internalAddon;
}
protected InternalAddon loadAddons() {
@@ -327,6 +331,28 @@ public abstract class AbstractPlatform implements Platform {
return 0;
}
private static final String moonrise = "Moonrise";
public static int getMoonriseGenerationThreadsWithReflection() {
try {
Class<?> prioritisedThreadPoolClazz = Class.forName("ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool");
Method getCoreThreadsMethod = prioritisedThreadPoolClazz.getDeclaredMethod("getCoreThreads");
getCoreThreadsMethod.setAccessible(true);
Class<?> moonriseCommonClazz = Class.forName("ca.spottedleaf.moonrise.common.util.MoonriseCommon");
Object pool = moonriseCommonClazz.getDeclaredField("WORKER_POOL").get(null);
int threads = ((Thread[]) getCoreThreadsMethod.invoke(pool)).length;
logger.info("{} found, setting {} generation threads.", moonrise, threads);
return threads;
} catch (ClassNotFoundException e) {
logger.info("{} not found.", moonrise);
} catch (NoSuchMethodException | NoSuchFieldException e) {
logger.warn("{} found, but field/method not found this probably means {0} has changed its code and " +
"Terra has not updated to reflect that.", moonrise);
} catch (IllegalAccessException | InvocationTargetException e) {
logger.error("Failed to access thread values in {}, assuming 1 generation thread.", moonrise, e);
}
return 0;
}
@Override
public void register(TypeRegistry registry) {
@@ -55,7 +55,7 @@ public class ConfigRegistry extends OpenRegistryImpl<ConfigPack> {
for(File dir : Objects.requireNonNull(packsFolder.listFiles(File::isDirectory))) {
try {
load(dir, platform);
} catch(ConfigException e) {
} catch(RuntimeException e) {
logger.error("Error loading config pack {}", dir.getName(), e);
valid = false;
}
@@ -65,7 +65,7 @@ public class ConfigRegistry extends OpenRegistryImpl<ConfigPack> {
try {
logger.info("Loading ZIP archive: {}", zip.getName());
load(new ZipFile(zip), platform);
} catch(IOException | ConfigException e) {
} catch(IOException | RuntimeException e) {
logger.error("Error loading config pack {}", zip.getName(), e);
valid = false;
}
+5 -1
View File
@@ -1,10 +1,14 @@
plugins {
id("io.papermc.paperweight.userdev")
id("xyz.jpenilla.run-paper") version Versions.Bukkit.runPaper
}
dependencies {
// Required for :platforms:bukkit:runDevBundleServer task
paperweight.paperDevBundle(Versions.Bukkit.paperDevBundle)
shaded(project(":platforms:bukkit:common"))
shaded(project(":platforms:bukkit:nms:v1_21_5", configuration = "reobf"))
shaded(project(":platforms:bukkit:nms:v1_21_7"))
shaded("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper)
}
+2
View File
@@ -7,6 +7,8 @@ dependencies {
compileOnly("io.papermc.paper", "paper-api", Versions.Bukkit.paper)
compileOnly("org.mvplugins.multiverse.core", "multiverse-core", Versions.Bukkit.multiverse)
shadedApi("io.papermc", "paperlib", Versions.Bukkit.paperLib)
shadedApi("com.google.guava", "guava", Versions.Libraries.Internal.guava)
@@ -21,20 +21,18 @@ import com.dfsek.tectonic.api.TypeRegistry;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.terra.bukkit.nms.Initializer;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryKey;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.List;
import java.util.Locale;
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.handle.ItemHandle;
import com.dfsek.terra.api.handle.WorldHandle;
@@ -57,7 +55,7 @@ public class PlatformImpl extends AbstractPlatform {
private int generationThreads;
public PlatformImpl(TerraBukkitPlugin plugin) {
generationThreads = getGenerationThreadsWithReflection("ca.spottedleaf.moonrise.common.util.MoonriseCommon", "WORKER_THREADS", "Moonrise");
generationThreads = getMoonriseGenerationThreadsWithReflection();
if (generationThreads == 0) {
generationThreads = 1;
}
@@ -97,11 +95,6 @@ public class PlatformImpl extends AbstractPlatform {
plugin.getGlobalRegionScheduler().run(plugin, task -> runnable.run());
}
@Override
protected Iterable<BaseAddon> platformAddon() {
return List.of(Initializer.nmsAddon(this));
}
@Override
public @NotNull WorldHandle getWorldHandle() {
return handle;
@@ -131,8 +124,9 @@ public class PlatformImpl extends AbstractPlatform {
}
private BukkitPlatformBiome parseBiome(String id, DepthTracker depthTracker) throws LoadException {
if(!id.startsWith("minecraft:")) throw new LoadException("Invalid biome identifier " + id, depthTracker);
return new BukkitPlatformBiome(org.bukkit.block.Biome.valueOf(id.toUpperCase(Locale.ROOT).substring(10)));
protected BukkitPlatformBiome parseBiome(String id, DepthTracker depthTracker) throws LoadException {
NamespacedKey key = NamespacedKey.fromString(id);
if(key == null || !key.namespace().equals("minecraft")) throw new LoadException("Invalid biome identifier " + id, depthTracker);
return new BukkitPlatformBiome(RegistryAccess.registryAccess().getRegistry(RegistryKey.BIOME).getOrThrow(key));
}
}
@@ -51,7 +51,7 @@ import com.dfsek.terra.bukkit.world.BukkitAdapter;
public class TerraBukkitPlugin extends JavaPlugin {
private static final Logger logger = LoggerFactory.getLogger(TerraBukkitPlugin.class);
private final PlatformImpl platform = new PlatformImpl(this);
private PlatformImpl platform;
private final Map<String, com.dfsek.terra.api.world.chunk.generation.ChunkGenerator> generatorMap = new HashMap<>();
private AsyncScheduler asyncScheduler = this.getServer().getAsyncScheduler();
@@ -64,13 +64,14 @@ public class TerraBukkitPlugin extends JavaPlugin {
return;
}
platform.getEventManager().callEvent(new PlatformInitializationEvent());
if(!Initializer.init(platform)) {
platform = Initializer.init(this);
if(platform == null) {
Bukkit.getPluginManager().disablePlugin(this);
return;
}
platform.getEventManager().callEvent(new PlatformInitializationEvent());
try {
LegacyPaperCommandManager<CommandSender> commandManager = getCommandSenderPaperCommandManager();
@@ -87,7 +88,7 @@ public class TerraBukkitPlugin extends JavaPlugin {
return;
}
Bukkit.getPluginManager().registerEvents(new CommonListener(), this); // Register master event listener
Bukkit.getPluginManager().registerEvents(new CommonListener(platform), this); // Register master event listener
PaperUtil.checkPaper(this);
}
@@ -0,0 +1,53 @@
package com.dfsek.terra.bukkit.hooks;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.registry.key.Keyed;
import org.mvplugins.multiverse.core.MultiverseCoreApi;
import org.mvplugins.multiverse.core.world.generators.GeneratorPlugin;
import org.mvplugins.multiverse.external.jetbrains.annotations.NotNull;
import org.mvplugins.multiverse.external.jetbrains.annotations.Nullable;
import java.util.Collection;
public final class MultiverseGeneratorPluginHook implements GeneratorPlugin {
private final Platform platform;
public MultiverseGeneratorPluginHook(Platform platform) {
this.platform = platform;
}
@Override
public @NotNull Collection<String> suggestIds(@Nullable String s) {
return platform.getConfigRegistry().entries().stream()
.map(Keyed::getID)
.toList();
}
@Override
public @Nullable Collection<String> getExampleUsages() {
return platform.getConfigRegistry()
.entries()
.stream()
.map(Keyed::getID)
.map("/mv create example_world NORMAL -g Terra:%s"::formatted)
.limit(5) // reasonable amount
.toList();
}
@Override
public @Nullable String getInfoLink() {
return "https://terra.polydev.org/";
}
@Override
public @NotNull String getPluginName() {
return "Terra";
}
public static void register(Platform platform) {
MultiverseCoreApi.get().getGeneratorProvider()
.registerGeneratorPlugin(new MultiverseGeneratorPluginHook(platform));
}
}
@@ -17,13 +17,100 @@
package com.dfsek.terra.bukkit.listeners;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper;
import com.dfsek.terra.bukkit.hooks.MultiverseGeneratorPluginHook;
import com.dfsek.terra.bukkit.world.BukkitBiomeInfo;
import com.dfsek.terra.bukkit.world.BukkitPlatformBiome;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.Wolf.Variant;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.server.PluginEnableEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
/**
* Listener for events on all implementations.
*/
public class CommonListener implements Listener {
public CommonListener() {
private static final Logger logger = LoggerFactory.getLogger(CommonListener.class);
private static final List<SpawnReason> WOLF_VARIANT_SPAWN_REASONS = List.of(
SpawnReason.SPAWNER, SpawnReason.TRIAL_SPAWNER, SpawnReason.SPAWNER_EGG, SpawnReason.DEFAULT
);
private final Platform platform;
public CommonListener(Platform platform) {
this.platform = platform;
}
@EventHandler
public void onPluginEnable(PluginEnableEvent event) {
if(event.getPlugin().getName().equals("Multiverse-Core")) {
try {
Class.forName("org.mvplugins.multiverse.core.MultiverseCoreApi");
MultiverseGeneratorPluginHook.register(platform);
} catch(ClassNotFoundException e) {
logger.debug("Multiverse v5 is not installed.");
} catch(IllegalStateException e) {
logger.error("Failed to register Terra generator plugin to multiverse.", e);
}
}
}
@EventHandler
public void onWolfSpawn(CreatureSpawnEvent event) {
if (!(event.getEntity() instanceof Wolf wolf)) {
return;
}
// Doesn't apply if variant has already been applied
if (wolf.getVariant() != Variant.PALE) {
return;
}
if (!WOLF_VARIANT_SPAWN_REASONS.contains(event.getSpawnReason())) {
return;
}
World world = wolf.getWorld();
if (!(world.getGenerator() instanceof BukkitChunkGeneratorWrapper wrapper)) {
return;
}
ConfigPack pack = platform.getConfigRegistry().get(wrapper.getPack().getRegistryKey()).orElse(null);
if (pack == null) {
return;
}
NamespacedKey biomeKey = wolf.getWorld().getBiome(wolf.getLocation()).getKey();
pack.getBiomeProvider().stream()
.filter(biome -> {
NamespacedKey key = ((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
.get(BukkitBiomeInfo.class)
.biomeKey();
return key.equals(biomeKey);
})
.findFirst()
.ifPresent(biome -> {
NamespacedKey vanillaBiomeKey = ((BukkitPlatformBiome) biome.getPlatformBiome()).getHandle().getKey();
switch(vanillaBiomeKey.toString()) {
case "minecraft:snowy_taiga" -> wolf.setVariant(Variant.ASHEN);
case "minecraft:old_growth_pine_taiga" -> wolf.setVariant(Variant.BLACK);
case "minecraft:old_growth_spruce_taiga" -> wolf.setVariant(Variant.CHESTNUT);
case "minecraft:grove" -> wolf.setVariant(Variant.SNOWY);
case "minecraft:forest" -> wolf.setVariant(Variant.WOODS);
}
});
}
}
@@ -1,6 +1,6 @@
package com.dfsek.terra.bukkit.nms;
import com.dfsek.terra.bukkit.BukkitAddon;
import com.dfsek.terra.bukkit.TerraBukkitPlugin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -13,13 +13,11 @@ public interface Initializer {
String NMS = VersionUtil.getMinecraftVersionInfo().toString().replace(".", "_");
String TERRA_PACKAGE = Initializer.class.getPackageName();
static boolean init(PlatformImpl platform) {
static PlatformImpl init(TerraBukkitPlugin plugin) {
Logger logger = LoggerFactory.getLogger(Initializer.class);
Initializer initializer = constructInitializer();
if(initializer != null) {
initializer.initialize(platform);
} else {
PlatformImpl platform = constructPlatform(plugin);
if (platform == null) {
logger.error("NMS bindings for version {} do not exist. Support for this version is limited.", NMS);
logger.error("This is usually due to running Terra on an unsupported Minecraft version.");
String bypassKey = "IKnowThereAreNoNMSBindingsFor" + NMS + "ButIWillProceedAnyway";
@@ -27,7 +25,7 @@ public interface Initializer {
logger.error("Because of this **TERRA HAS BEEN DISABLED**.");
logger.error("Do not come ask us why it is not working.");
logger.error("If you wish to proceed anyways, you can add the JVM System Property \"{}\" to enable the plugin.", bypassKey);
return false;
return null;
} else {
logger.error("");
logger.error("");
@@ -43,20 +41,21 @@ public interface Initializer {
}
}
return true;
return platform;
}
static BukkitAddon nmsAddon(PlatformImpl platform) {
Initializer initializer = constructInitializer();
return initializer != null ? initializer.getNMSAddon(platform) : new BukkitAddon(platform);
}
private static Initializer constructInitializer() {
private static PlatformImpl constructPlatform(TerraBukkitPlugin plugin) {
try {
String packageVersion = NMS;
Class<?> initializerClass = Class.forName(TERRA_PACKAGE + "." + packageVersion + ".NMSInitializer");
if (NMS.equals("v1_21_5") || NMS.equals("v1_21_6")) {
packageVersion = "v1_21_7";
}
Class<?> platformClass = Class.forName(TERRA_PACKAGE + "." + packageVersion + ".NMSPlatform");
try {
return (Initializer) initializerClass.getConstructor().newInstance();
return (PlatformImpl) platformClass
.getConstructor(TerraBukkitPlugin.class)
.newInstance(plugin);
} catch(ReflectiveOperationException e) {
throw new RuntimeException("Error initializing NMS bindings. Report this to Terra.", e);
}
@@ -64,8 +63,4 @@ public interface Initializer {
return null;
}
}
void initialize(PlatformImpl plugin);
BukkitAddon getNMSAddon(PlatformImpl plugin);
}
@@ -0,0 +1,8 @@
package com.dfsek.terra.bukkit.world;
import com.dfsek.terra.api.properties.Properties;
import org.bukkit.NamespacedKey;
public record BukkitBiomeInfo(NamespacedKey biomeKey) implements Properties {}
@@ -1,22 +0,0 @@
package com.dfsek.terra.bukkit.nms.v1_21_5;
import com.dfsek.terra.bukkit.BukkitAddon;
import org.bukkit.Bukkit;
import com.dfsek.terra.bukkit.PlatformImpl;
import com.dfsek.terra.bukkit.nms.Initializer;
public class NMSInitializer implements Initializer {
@Override
public void initialize(PlatformImpl platform) {
AwfulBukkitHacks.registerBiomes(platform.getRawConfigRegistry());
Bukkit.getPluginManager().registerEvents(new NMSInjectListener(), platform.getPlugin());
}
@Override
public BukkitAddon getNMSAddon(PlatformImpl plugin) {
return new NMSAddon(plugin);
}
}
@@ -6,10 +6,4 @@ dependencies {
api(project(":platforms:bukkit:common"))
paperweight.paperDevBundle(Versions.Bukkit.paperDevBundle)
implementation("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper)
}
tasks {
assemble {
dependsOn("reobfJar")
}
}
@@ -1,6 +1,8 @@
package com.dfsek.terra.bukkit.nms.v1_21_5;
package com.dfsek.terra.bukkit.nms.v1_21_7;
import com.dfsek.terra.bukkit.nms.v1_21_5.config.VanillaBiomeProperties;
import com.dfsek.terra.bukkit.nms.v1_21_7.config.VanillaBiomeProperties;
import com.dfsek.terra.bukkit.world.BukkitBiomeInfo;
import net.minecraft.core.Holder;
import net.minecraft.core.Holder.Reference;
@@ -12,6 +14,7 @@ import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.entity.npc.VillagerType;
import net.minecraft.world.level.biome.Biome;
import org.bukkit.NamespacedKey;
import org.slf4j.Logger;
@@ -22,6 +25,7 @@ import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@@ -46,6 +50,7 @@ public class AwfulBukkitHacks {
configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> {
try {
BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome();
NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey();
ResourceLocation vanillaMinecraftKey = ResourceLocation.fromNamespaceAndPath(vanillaBukkitKey.getNamespace(),
vanillaBukkitKey.getKey());
@@ -54,16 +59,22 @@ public class AwfulBukkitHacks {
Biome platform = NMSBiomeInjector.createBiome(biomeRegistry.get(vanillaMinecraftKey).orElseThrow().value(), vanillaBiomeProperties);
ResourceKey<Biome> delegateKey = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath("terra", NMSBiomeInjector.createBiomeID(pack, key))
);
ResourceLocation delegateMinecraftKey = ResourceLocation.fromNamespaceAndPath("terra", NMSBiomeInjector.createBiomeID(pack, key));
NamespacedKey delegateBukkitKey = NamespacedKey.fromString(delegateMinecraftKey.toString());
ResourceKey<Biome> delegateKey = ResourceKey.create(Registries.BIOME, delegateMinecraftKey);
Reference<Biome> holder = biomeRegistry.register(delegateKey, platform, RegistrationInfo.BUILT_IN);
Reflection.REFERENCE.invokeBindValue(holder, platform); // IMPORTANT: bind holder.
platformBiome.getContext().put(new BukkitBiomeInfo(delegateBukkitKey));
platformBiome.getContext().put(new NMSBiomeInfo(delegateKey));
Map<ResourceKey<Biome>, ResourceKey<VillagerType>> villagerMap = Reflection.VILLAGER_TYPE.getByBiome();
villagerMap.put(delegateKey,
Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(),
villagerMap.getOrDefault(delegateKey, VillagerType.PLAINS)));
terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location());
LOGGER.debug("Registered biome: " + delegateKey);
@@ -1,11 +1,11 @@
package com.dfsek.terra.bukkit.nms.v1_21_5;
package com.dfsek.terra.bukkit.nms.v1_21_7;
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_5.config.VanillaBiomeProperties;
import com.dfsek.terra.bukkit.nms.v1_21_7.config.VanillaBiomeProperties;
public class NMSAddon extends BukkitAddon {
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_5;
package com.dfsek.terra.bukkit.nms.v1_21_7;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.biome.Biome;
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_5;
package com.dfsek.terra.bukkit.nms.v1_21_7;
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_5.config.VanillaBiomeProperties;
import com.dfsek.terra.bukkit.nms.v1_21_7.config.VanillaBiomeProperties;
public class NMSBiomeInjector {
@@ -33,9 +33,8 @@ public class NMSBiomeInjector {
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()))
.grassColorModifier(Objects.requireNonNullElse(vanillaBiomeProperties.getGrassColorModifier(), vanilla.getSpecialEffects().getGrassColorModifier()));
// .grassColorOverride(Objects.requireNonNullElse(vanillaBiomeProperties.getGrassColor(), vanilla.getSpecialEffects().getGrassColorOverride().orElseGet(() -> Reflection.BIOME.invokeGrassColorFromTexture(vanilla))))
// .foliageColorOverride(Objects.requireNonNullElse(vanillaBiomeProperties.getFoliageColor(), vanilla.getFoliageColor()));
.grassColorModifier(Objects.requireNonNullElse(vanillaBiomeProperties.getGrassColorModifier(), vanilla.getSpecialEffects().getGrassColorModifier()))
.backgroundMusicVolume(Objects.requireNonNullElse(vanillaBiomeProperties.getMusicVolume(), vanilla.getBackgroundMusicVolume()));
if(vanillaBiomeProperties.getGrassColor() == null) {
vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride);
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_5;
package com.dfsek.terra.bukkit.nms.v1_21_7;
import com.mojang.serialization.MapCodec;
import net.minecraft.core.Holder;
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_5;
package com.dfsek.terra.bukkit.nms.v1_21_7;
import com.mojang.serialization.MapCodec;
import net.minecraft.core.BlockPos;
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_5;
package com.dfsek.terra.bukkit.nms.v1_21_7;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ServerLevel;
@@ -0,0 +1,108 @@
package com.dfsek.terra.bukkit.nms.v1_21_7;
import com.dfsek.tectonic.api.TypeRegistry;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.terra.addon.InternalAddon;
import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.world.biome.PlatformBiome;
import com.dfsek.terra.bukkit.PlatformImpl;
import com.dfsek.terra.bukkit.TerraBukkitPlugin;
import com.dfsek.terra.bukkit.nms.v1_21_7.config.BiomeAdditionsSoundTemplate;
import com.dfsek.terra.bukkit.nms.v1_21_7.config.BiomeMoodSoundTemplate;
import com.dfsek.terra.bukkit.nms.v1_21_7.config.BiomeParticleConfigTemplate;
import com.dfsek.terra.bukkit.nms.v1_21_7.config.EntityTypeTemplate;
import com.dfsek.terra.bukkit.nms.v1_21_7.config.MusicSoundTemplate;
import com.dfsek.terra.bukkit.nms.v1_21_7.config.SoundEventTemplate;
import com.dfsek.terra.bukkit.nms.v1_21_7.config.SpawnCostConfig;
import com.dfsek.terra.bukkit.nms.v1_21_7.config.SpawnEntryConfig;
import com.dfsek.terra.bukkit.nms.v1_21_7.config.SpawnSettingsTemplate;
import com.dfsek.terra.bukkit.nms.v1_21_7.config.SpawnTypeConfig;
import com.dfsek.terra.bukkit.nms.v1_21_7.config.VillagerTypeTemplate;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.Music;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.entity.npc.VillagerType;
import net.minecraft.world.level.biome.AmbientAdditionsSettings;
import net.minecraft.world.level.biome.AmbientMoodSettings;
import net.minecraft.world.level.biome.AmbientParticleSettings;
import net.minecraft.world.level.biome.Biome.Precipitation;
import net.minecraft.world.level.biome.Biome.TemperatureModifier;
import net.minecraft.world.level.biome.BiomeSpecialEffects.GrassColorModifier;
import net.minecraft.world.level.biome.MobSpawnSettings;
import org.bukkit.Bukkit;
import java.util.List;
import java.util.Locale;
public class NMSPlatform extends PlatformImpl {
public NMSPlatform(TerraBukkitPlugin plugin) {
super(plugin);
Bukkit.getPluginManager().registerEvents(new NMSInjectListener(), plugin);
}
@Override
public void register(TypeRegistry registry) {
super.register(registry);
registry.registerLoader(PlatformBiome.class, (type, o, loader, depthTracker) -> parseBiome((String) o, depthTracker))
.registerLoader(ResourceLocation.class, (type, o, loader, depthTracker) -> {
ResourceLocation identifier = ResourceLocation.tryParse((String) o);
if(identifier == null)
throw new LoadException("Invalid identifier: " + o, depthTracker);
return identifier;
})
.registerLoader(Precipitation.class, (type, o, loader, depthTracker) -> Precipitation.valueOf(((String) o).toUpperCase(
Locale.ROOT)))
.registerLoader(GrassColorModifier.class,
(type, o, loader, depthTracker) -> GrassColorModifier.valueOf(((String) o).toUpperCase(
Locale.ROOT)))
.registerLoader(GrassColorModifier.class,
(type, o, loader, depthTracker) -> TemperatureModifier.valueOf(((String) o).toUpperCase(
Locale.ROOT)))
.registerLoader(MobCategory.class, (type, o, loader, depthTracker) -> MobCategory.valueOf((String) o))
.registerLoader(AmbientParticleSettings.class, BiomeParticleConfigTemplate::new)
.registerLoader(SoundEvent.class, SoundEventTemplate::new)
.registerLoader(AmbientMoodSettings.class, BiomeMoodSoundTemplate::new)
.registerLoader(AmbientAdditionsSettings.class, BiomeAdditionsSoundTemplate::new)
.registerLoader(Music.class, MusicSoundTemplate::new)
.registerLoader(EntityType.class, EntityTypeTemplate::new)
.registerLoader(SpawnCostConfig.class, SpawnCostConfig::new)
.registerLoader(SpawnEntryConfig.class, SpawnEntryConfig::new)
.registerLoader(SpawnTypeConfig.class, SpawnTypeConfig::new)
.registerLoader(MobSpawnSettings.class, SpawnSettingsTemplate::new)
.registerLoader(VillagerType.class, VillagerTypeTemplate::new);
}
@Override
protected InternalAddon load() {
InternalAddon internalAddon = super.load();
this.getEventManager().getHandler(FunctionalEventHandler.class)
.register(internalAddon, PlatformInitializationEvent.class)
.priority(1)
.then(event -> AwfulBukkitHacks.registerBiomes(this.getRawConfigRegistry()))
.global();
return internalAddon;
}
@Override
protected Iterable<BaseAddon> platformAddon() {
return List.of(new NMSAddon(this));
}
}
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_5;
package com.dfsek.terra.bukkit.nms.v1_21_7;
import net.minecraft.world.level.LevelHeightAccessor;
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_5;
package com.dfsek.terra.bukkit.nms.v1_21_7;
import net.minecraft.core.Holder;
import net.minecraft.core.Holder.Reference;
@@ -7,6 +7,7 @@ import net.minecraft.core.MappedRegistry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.tags.TagKey;
import net.minecraft.world.entity.npc.VillagerType;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.StructureManager;
import net.minecraft.world.level.biome.Biome;
@@ -36,6 +37,7 @@ public class Reflection {
public static final HolderReferenceProxy HOLDER_REFERENCE;
public static final HolderSetNamedProxy HOLDER_SET;
public static final BiomeProxy BIOME;
public static final VillagerTypeProxy VILLAGER_TYPE;
static {
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
@@ -50,6 +52,7 @@ public class Reflection {
HOLDER_REFERENCE = reflectionProxyFactory.reflectionProxy(HolderReferenceProxy.class);
HOLDER_SET = reflectionProxyFactory.reflectionProxy(HolderSetNamedProxy.class);
BIOME = reflectionProxyFactory.reflectionProxy(BiomeProxy.class);
VILLAGER_TYPE = reflectionProxyFactory.reflectionProxy(VillagerTypeProxy.class);
}
@@ -121,4 +124,11 @@ public class Reflection {
@MethodName("getGrassColorFromTexture")
int invokeGrassColorFromTexture(Biome instance);
}
@Proxies(VillagerType.class)
public interface VillagerTypeProxy {
@Static
@FieldGetter("BY_BIOME")
Map<ResourceKey<Biome>, ResourceKey<VillagerType>> getByBiome();
}
}
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_5;
package com.dfsek.terra.bukkit.nms.v1_21_7;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
package com.dfsek.terra.bukkit.nms.v1_21_7.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_5.config;
package com.dfsek.terra.bukkit.nms.v1_21_7.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_5.config;
package com.dfsek.terra.bukkit.nms.v1_21_7.config;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
@@ -6,10 +6,15 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.commands.arguments.ParticleArgument;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.HolderLookup.Provider;
import net.minecraft.core.HolderLookup.RegistryLookup;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.level.biome.AmbientParticleSettings;
import java.util.stream.Stream;
public class BiomeParticleConfigTemplate implements ObjectTemplate<AmbientParticleSettings> {
@Value("particle")
@@ -18,17 +23,18 @@ public class BiomeParticleConfigTemplate implements ObjectTemplate<AmbientPartic
@Value("probability")
@Default
private Integer probability = null;
private Float probability = 0.1f;
@Override
public AmbientParticleSettings get() {
if(particle == null || probability == null) {
if(particle == null) {
return null;
}
try {
return new AmbientParticleSettings(ParticleArgument.readParticle(new StringReader(particle),
(Provider) BuiltInRegistries.PARTICLE_TYPE.asHolderIdMap()), probability);
HolderLookup.Provider.create(Stream.of(BuiltInRegistries.PARTICLE_TYPE))), probability);
} catch(CommandSyntaxException e) {
throw new RuntimeException(e);
}
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
package com.dfsek.terra.bukkit.nms.v1_21_7.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_5.config;
package com.dfsek.terra.bukkit.nms.v1_21_7.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_5.config;
package com.dfsek.terra.bukkit.nms.v1_21_7.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_5.config;
package com.dfsek.terra.bukkit.nms.v1_21_7.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_5.config;
package com.dfsek.terra.bukkit.nms.v1_21_7.config;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
@@ -28,7 +28,7 @@ public class SpawnEntryConfig implements ObjectTemplate<SpawnEntryConfig> {
return weight;
}
public SpawnerData getSpawnerData() {
public SpawnerData getSpawnEntry() {
return new SpawnerData(type, minGroupSize, maxGroupSize);
}
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
package com.dfsek.terra.bukkit.nms.v1_21_7.config;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
@@ -33,7 +33,7 @@ public class SpawnSettingsTemplate implements ObjectTemplate<MobSpawnSettings> {
for(SpawnTypeConfig spawn : spawns) {
MobCategory group = spawn.getGroup();
for(SpawnEntryConfig entry : spawn.getEntries()) {
builder.addSpawn(group, entry.getWeight(), entry.getSpawnerData());
builder.addSpawn(group, entry.getWeight(), entry.getSpawnEntry());
}
}
for(SpawnCostConfig cost : costs) {
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
package com.dfsek.terra.bukkit.nms.v1_21_7.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_5.config;
package com.dfsek.terra.bukkit.nms.v1_21_7.config;
import com.dfsek.tectonic.api.config.template.ConfigTemplate;
import com.dfsek.tectonic.api.config.template.annotations.Default;
@@ -6,6 +6,7 @@ import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.api.properties.Properties;
import net.minecraft.resources.ResourceKey;
import net.minecraft.sounds.Music;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.entity.npc.VillagerType;
@@ -38,6 +39,10 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
@Default
private Integer foliageColor = null;
@Value("colors.dry-foliage")
@Default
private Integer dryFoliageColor = null;
@Value("colors.sky")
@Default
private Integer skyColor = null;
@@ -82,13 +87,17 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
@Default
private Music music = null;
@Value("sound.music-volume")
@Default
private Float musicVolume = null;
@Value("spawning")
@Default
private MobSpawnSettings spawnSettings = null;
@Value("villager-type")
@Default
private VillagerType villagerType = null;
private ResourceKey<VillagerType> villagerType = null;
public Integer getFogColor() {
return fogColor;
@@ -98,6 +107,10 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
return foliageColor;
}
public Integer getDryFoliageColor() {
return dryFoliageColor;
}
public Integer getGrassColor() {
return grassColor;
}
@@ -154,11 +167,15 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
return music;
}
public Float getMusicVolume() {
return musicVolume;
}
public MobSpawnSettings getSpawnSettings() {
return spawnSettings;
}
public VillagerType getVillagerType() {
public ResourceKey<VillagerType> getVillagerType() {
return villagerType;
}
}
@@ -1,20 +1,21 @@
package com.dfsek.terra.bukkit.nms.v1_21_5.config;
package com.dfsek.terra.bukkit.nms.v1_21_7.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.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.npc.VillagerType;
public class VillagerTypeTemplate implements ObjectTemplate<VillagerType> {
public class VillagerTypeTemplate implements ObjectTemplate<ResourceKey<VillagerType>> {
@Value("id")
@Default
private ResourceLocation id = null;
@Override
public VillagerType get() {
return BuiltInRegistries.VILLAGER_TYPE.get(id).orElseThrow().value();
public ResourceKey<VillagerType> get() {
return ResourceKey.create(BuiltInRegistries.VILLAGER_TYPE.key(), id);
}
}
+3 -1
View File
@@ -26,7 +26,9 @@ dependencies {
modImplementation("net.fabricmc:fabric-loader:${Versions.Mod.fabricLoader}")
modImplementation("org.incendo", "cloud-fabric", Versions.Fabric.cloud)
modImplementation("org.incendo", "cloud-fabric", Versions.Fabric.cloud) {
exclude("me.lucko", "fabric-permissions-api")
}
include("org.incendo", "cloud-fabric", Versions.Fabric.cloud)
modRuntimeOnly("net.fabricmc.fabric-api", "fabric-api", Versions.Fabric.fabricAPI)
@@ -35,7 +35,7 @@
"depends": {
"fabricloader": ">=0.16.10",
"java": ">=21",
"minecraft": ">=1.21.4",
"minecraft": "1.21.7",
"fabric": "*"
}
}
@@ -52,7 +52,7 @@ public final class MinestomPlatform extends AbstractPlatform {
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());
LOGGER.info("Replaced pack in chunk generator for instance {}", world.getUuid());
});
}
});
@@ -7,9 +7,9 @@ import com.dfsek.tectonic.api.loader.type.TypeLoader;
import com.dfsek.terra.api.world.biome.PlatformBiome;
import net.kyori.adventure.key.Key;
import net.minestom.server.MinecraftServer;
import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.world.biome.Biome;
import org.jetbrains.annotations.NotNull;
@@ -23,7 +23,7 @@ public class MinestomBiomeLoader implements TypeLoader<PlatformBiome> {
public PlatformBiome load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader,
DepthTracker depthTracker) throws LoadException {
String id = (String) o;
NamespaceID biomeID = NamespaceID.from(id);
Key biomeID = Key.key(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);
@@ -4,11 +4,17 @@ 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,57 @@
package com.dfsek.terra.minestom.block;
import com.dfsek.terra.api.util.vector.Vector3;
import net.minestom.server.coordinate.BlockVec;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import com.dfsek.terra.api.block.entity.BlockEntity;
import com.dfsek.terra.api.block.state.BlockState;
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);
}
}
@@ -1,15 +1,14 @@
package com.dfsek.terra.minestom.block;
import net.minestom.server.instance.block.Block;
import java.util.Objects;
import java.util.stream.Collectors;
import com.dfsek.terra.api.block.BlockType;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.state.properties.Property;
import net.minestom.server.instance.block.Block;
import java.util.HashMap;
import java.util.Objects;
import java.util.stream.Collectors;
public class MinestomBlockState implements BlockState {
private final Block block;
@@ -23,24 +22,10 @@ public class MinestomBlockState implements BlockState {
}
public MinestomBlockState(String data) {
if(!data.contains("[")) {
block = Block.fromNamespaceId(data);
return;
block = Block.fromState(data);
if (block == null) {
throw new IllegalArgumentException("Invalid block state: " + data);
}
String[] split = data.split("\\[");
String namespaceId = split[0];
String properties = split[1].substring(0, split[1].length() - 1);
Block block = Block.fromNamespaceId(namespaceId);
HashMap<String, String> propertiesMap = new HashMap<>();
for(String property : properties.split(",")) {
String[] kv = property.split("=");
propertiesMap.put(kv[0].strip(), kv[1].strip());
}
assert block != null;
this.block = block.withProperties(propertiesMap);
}
@Override
@@ -70,7 +55,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;
}
@@ -8,7 +8,7 @@ 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
@@ -5,47 +5,47 @@ import com.dfsek.terra.api.inventory.item.Enchantment;
import net.minestom.server.MinecraftServer;
import net.minestom.server.item.Material;
import net.minestom.server.utils.NamespaceID;
import java.util.Objects;
import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.registry.RegistryKey;
public class MinestomEnchantment implements Enchantment {
private final net.minestom.server.item.enchant.Enchantment delegate;
private final String id;
private final net.minestom.server.item.enchant.Enchantment registryItem;
private final RegistryKey<net.minestom.server.item.enchant.Enchantment> id;
private static final DynamicRegistry<net.minestom.server.item.enchant.Enchantment> enchantmentRegistry =
MinecraftServer.getEnchantmentRegistry();
public MinestomEnchantment(net.minestom.server.item.enchant.Enchantment delegate) {
this.delegate = delegate;
id = Objects.requireNonNull(delegate.registry()).raw();
public MinestomEnchantment(RegistryKey<net.minestom.server.item.enchant.Enchantment> id) {
this.id = id;
this.registryItem = enchantmentRegistry.get(id);
}
public MinestomEnchantment(String id) {
this.delegate = MinecraftServer.getEnchantmentRegistry().get(NamespaceID.from(id));
this.id = id;
this(RegistryKey.unsafeOf(id));
}
@Override
public boolean canEnchantItem(ItemStack itemStack) {
return delegate.supportedItems().contains((Material) itemStack.getType().getHandle());
return registryItem.supportedItems().contains((Material) itemStack.getType().getHandle());
}
@Override
public boolean conflictsWith(Enchantment other) {
return delegate.exclusiveSet().contains(NamespaceID.from(((MinestomEnchantment) other).id));
return registryItem.exclusiveSet().contains(((MinestomEnchantment) other).id);
}
@Override
public String getID() {
return id;
return id.name();
}
@Override
public int getMaxLevel() {
return delegate.maxLevel();
return registryItem.maxLevel();
}
@Override
public net.minestom.server.item.enchant.Enchantment getHandle() {
return delegate;
return registryItem;
}
}
@@ -23,6 +23,6 @@ public class MinestomItemHandle implements ItemHandle {
@Override
public Set<Enchantment> getEnchantments() {
return MinecraftServer.getEnchantmentRegistry().values().stream().map(MinestomEnchantment::new).collect(Collectors.toSet());
return MinecraftServer.getEnchantmentRegistry().keys().stream().map(MinestomEnchantment::new).collect(Collectors.toSet());
}
}
@@ -6,11 +6,11 @@ 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;
import net.minestom.server.registry.DynamicRegistry.Key;
import net.minestom.server.registry.RegistryKey;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
@@ -47,11 +47,10 @@ 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(
new MinestomEnchantment(Objects.requireNonNull(MinecraftServer.getEnchantmentRegistry().get(enchantmentKey))), integer);
enchantments.put(new MinestomEnchantment(enchantmentKey), integer);
});
}
return new MinestomItemMeta(enchantments);
@@ -59,7 +58,7 @@ public class MinestomItemStack implements com.dfsek.terra.api.inventory.ItemStac
@Override
public void setItemMeta(ItemMeta meta) {
HashMap<Key<net.minestom.server.item.enchant.Enchantment>, Integer> enchantments = new HashMap<>();
HashMap<RegistryKey<net.minestom.server.item.enchant.Enchantment>, Integer> enchantments = new HashMap<>();
DynamicRegistry<net.minestom.server.item.enchant.Enchantment> registry = MinecraftServer.getEnchantmentRegistry();
meta.getEnchantments().forEach((key, value) -> {
MinestomEnchantment enchantment = (MinestomEnchantment) key;
@@ -67,6 +66,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);
}
}
@@ -14,7 +14,7 @@ public class MinestomMaterial implements Item {
}
public MinestomMaterial(String id) {
this.delegate = Material.fromNamespaceId(id);
this.delegate = Material.fromKey(id);
}
@Override
@@ -22,9 +22,12 @@ public class TerraMinestomWorldBuilder {
private ConfigPack pack;
private long seed = new Random().nextLong();
private EntityFactory entityFactory = new DefaultEntityFactory();
private BlockEntityFactory blockEntityFactory = new DefaultBlockEntityFactory();
private BlockEntityFactory blockEntityFactory;
private TerraMinestomWorldBuilder(Instance instance) { this.instance = instance; }
private TerraMinestomWorldBuilder(Instance instance) {
this.instance = instance;
this.blockEntityFactory = new DefaultBlockEntityFactory(instance);
}
public static TerraMinestomWorldBuilder from(Instance instance) {
return new TerraMinestomWorldBuilder(instance);
@@ -90,7 +90,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, SpawnEntryConfig::new)
.registerLoader(SpawnEntryConfig.class, SpawnEntryConfig::new)
.registerLoader(SpawnTypeConfig.class, SpawnTypeConfig::new)
.registerLoader(SpawnSettings.class, SpawnSettingsTemplate::new)
.registerLoader(VillagerType.class, VillagerTypeTemplate::new);
@@ -10,6 +10,8 @@ import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.world.biome.BiomeParticleConfig;
import java.util.stream.Stream;
public class BiomeParticleConfigTemplate implements ObjectTemplate<BiomeParticleConfig> {
@Value("particle")
@@ -18,19 +20,19 @@ public class BiomeParticleConfigTemplate implements ObjectTemplate<BiomeParticle
@Value("probability")
@Default
private Integer probability = null;
private Float probability = 0.1f;
@Override
public BiomeParticleConfig get() {
if(particle == null || probability == null) {
if(particle == null) {
return null;
}
try {
return new BiomeParticleConfig(
ParticleEffectArgumentType.readParameters(new StringReader(particle),
(RegistryWrapper.WrapperLookup) Registries.PARTICLE_TYPE),
probability);
RegistryWrapper.WrapperLookup.of(Stream.of(Registries.PARTICLE_TYPE))),
probability);
} catch(CommandSyntaxException e) {
throw new RuntimeException(e);
}
@@ -7,7 +7,7 @@ import net.minecraft.entity.EntityType;
import net.minecraft.world.biome.SpawnSettings.SpawnEntry;
public class SpawnEntryConfig implements ObjectTemplate<SpawnEntry> {
public class SpawnEntryConfig implements ObjectTemplate<SpawnEntryConfig> {
@Value("type")
@Default
private EntityType<?> type = null;
@@ -28,8 +28,12 @@ public class SpawnEntryConfig implements ObjectTemplate<SpawnEntry> {
return weight;
}
@Override
public SpawnEntry get() {
public SpawnEntry getSpawnEntry() {
return new SpawnEntry(type, minGroupSize, maxGroupSize);
}
@Override
public SpawnEntryConfig get() {
return this;
}
}
@@ -27,8 +27,8 @@ public class SpawnSettingsTemplate implements ObjectTemplate<SpawnSettings> {
SpawnSettings.Builder builder = new SpawnSettings.Builder();
for(SpawnTypeConfig spawn : spawns) {
SpawnGroup group = spawn.getGroup();
for(SpawnEntryConfig entry : spawn.getEntry()) {
builder.spawn(group, entry.getWeight(), entry.get());
for(SpawnEntryConfig entry : spawn.getEntries()) {
builder.spawn(group, entry.getWeight(), entry.getSpawnEntry());
}
}
for(SpawnCostConfig cost : costs) {
@@ -15,14 +15,14 @@ public class SpawnTypeConfig implements ObjectTemplate<SpawnTypeConfig> {
@Value("entries")
@Default
private List<SpawnEntryConfig> entry = null;
private List<SpawnEntryConfig> entries = null;
public SpawnGroup getGroup() {
return group;
}
public List<SpawnEntryConfig> getEntry() {
return entry;
public List<SpawnEntryConfig> getEntries() {
return entries;
}
@Override
@@ -38,6 +38,10 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
@Default
private Integer foliageColor = null;
@Value("colors.dry-foliage")
@Default
private Integer dryFoliageColor = null;
@Value("colors.sky")
@Default
private Integer skyColor = null;
@@ -82,6 +86,10 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
@Default
private MusicSound music = null;
@Value("sound.music-volume")
@Default
private Float musicVolume = null;
@Value("spawning")
@Default
private SpawnSettings spawnSettings = null;
@@ -111,6 +119,10 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
return foliageColor;
}
public Integer getDryFoliageColor() {
return dryFoliageColor;
}
public Integer getSkyColor() {
return skyColor;
}
@@ -155,6 +167,10 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
return music;
}
public Float getMusicVolume() {
return musicVolume;
}
public SpawnSettings getSpawnSettings() {
return spawnSettings;
}
@@ -13,10 +13,10 @@ import net.minecraft.village.VillagerType;
public class VillagerTypeTemplate implements ObjectTemplate<RegistryKey<VillagerType>> {
@Value("id")
@Default
private String id = null;
private Identifier id = null;
@Override
public RegistryKey<VillagerType> get() {
return RegistryKey.of(RegistryKeys.VILLAGER_TYPE, Identifier.ofVanilla(id));
return RegistryKey.of(RegistryKeys.VILLAGER_TYPE, id);
}
}
@@ -1,28 +0,0 @@
package com.dfsek.terra.mod.mixin.fix;
import net.minecraft.entity.passive.BeeEntity.MoveToFlowerGoal;
import net.minecraft.entity.passive.BeeEntity.MoveToHiveGoal;
import net.minecraft.util.math.random.CheckedRandom;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import com.dfsek.terra.mod.CommonPlatform;
/**
* Bees spawning uses world.random without synchronization. This causes issues when spawning bees during world generation.
*/
@Mixin({
MoveToHiveGoal.class,
MoveToFlowerGoal.class
})
public class BeeMoveGoalsUnsynchronizedRandomAccessFix {
@Redirect(method = "<init>",
at = @At(value = "FIELD", target = "Lnet/minecraft/world/World;random:Lnet/minecraft/util/math/random/Random;"))
public Random redirectRandomAccess(World instance) {
return new CheckedRandom(CommonPlatform.get().getServer().getTicks()); // replace with new random seeded by tick time.
}
}
@@ -35,9 +35,25 @@ public class BiomeUtil {
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()))
.grassColorModifier(
Objects.requireNonNullElse(vanillaBiomeProperties.getGrassColorModifier(), vanilla.getEffects().getGrassColorModifier()))
.grassColor(Objects.requireNonNullElse(vanillaBiomeProperties.getGrassColor(),
vanilla.getEffects().getGrassColor().orElseGet(() -> ((BiomeInvoker) ((Object) vanilla)).invokeGetDefaultGrassColor())))
.foliageColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFoliageColor(), vanilla.getFoliageColor()));
.musicVolume(Objects.requireNonNullElse(vanillaBiomeProperties.getMusicVolume(), vanilla.getMusicVolume()));
if(vanillaBiomeProperties.getGrassColor() == null) {
vanilla.getEffects().getGrassColor().ifPresent(effects::grassColor);
} else {
effects.grassColor(vanillaBiomeProperties.getGrassColor());
}
if(vanillaBiomeProperties.getFoliageColor() == null) {
vanilla.getEffects().getFoliageColor().ifPresent(effects::foliageColor);
} else {
effects.foliageColor(vanillaBiomeProperties.getFoliageColor());
}
if(vanillaBiomeProperties.getDryFoliageColor() == null) {
vanilla.getEffects().getDryFoliageColor().ifPresent(effects::dryFoliageColor);
} else {
effects.dryFoliageColor(vanillaBiomeProperties.getDryFoliageColor());
}
if(vanillaBiomeProperties.getParticleConfig() == null) {
vanilla.getEffects().getParticleConfig().ifPresent(effects::particleConfig);
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"minecraft:snowy_taiga"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"minecraft:old_growth_pine_taiga"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"minecraft:old_growth_spruce_taiga"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"minecraft:taiga"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#minecraft:is_jungle"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"minecraft:grove"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#minecraft:is_savanna"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#minecraft:is_badlands"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"minecraft:forest"
]
}
@@ -0,0 +1,16 @@
{
"assets": {
"angry": "minecraft:entity/wolf/wolf_ashen_angry",
"tame": "minecraft:entity/wolf/wolf_ashen_tame",
"wild": "minecraft:entity/wolf/wolf_ashen"
},
"spawn_conditions": [
{
"condition": {
"type": "minecraft:biome",
"biomes": "#c:has_wolf_variant/ashen"
},
"priority": 1
}
]
}
@@ -0,0 +1,16 @@
{
"assets": {
"angry": "minecraft:entity/wolf/wolf_black_angry",
"tame": "minecraft:entity/wolf/wolf_black_tame",
"wild": "minecraft:entity/wolf/wolf_black"
},
"spawn_conditions": [
{
"condition": {
"type": "minecraft:biome",
"biomes": "#c:has_wolf_variant/black"
},
"priority": 1
}
]
}
@@ -0,0 +1,16 @@
{
"assets": {
"angry": "minecraft:entity/wolf/wolf_chestnut_angry",
"tame": "minecraft:entity/wolf/wolf_chestnut_tame",
"wild": "minecraft:entity/wolf/wolf_chestnut"
},
"spawn_conditions": [
{
"condition": {
"type": "minecraft:biome",
"biomes": "#c:has_wolf_variant/chestnut"
},
"priority": 1
}
]
}
@@ -0,0 +1,16 @@
{
"assets": {
"angry": "minecraft:entity/wolf/wolf_angry",
"tame": "minecraft:entity/wolf/wolf_tame",
"wild": "minecraft:entity/wolf/wolf"
},
"spawn_conditions": [
{
"condition": {
"type": "minecraft:biome",
"biomes": "#c:has_wolf_variant/pale"
},
"priority": 1
}
]
}
@@ -0,0 +1,16 @@
{
"assets": {
"angry": "minecraft:entity/wolf/wolf_rusty_angry",
"tame": "minecraft:entity/wolf/wolf_rusty_tame",
"wild": "minecraft:entity/wolf/wolf_rusty"
},
"spawn_conditions": [
{
"condition": {
"type": "minecraft:biome",
"biomes": "#c:has_wolf_variant/rusty"
},
"priority": 1
}
]
}
@@ -0,0 +1,16 @@
{
"assets": {
"angry": "minecraft:entity/wolf/wolf_snowy_angry",
"tame": "minecraft:entity/wolf/wolf_snowy_tame",
"wild": "minecraft:entity/wolf/wolf_snowy"
},
"spawn_conditions": [
{
"condition": {
"type": "minecraft:biome",
"biomes": "#c:has_wolf_variant/snowy"
},
"priority": 1
}
]
}
@@ -0,0 +1,16 @@
{
"assets": {
"angry": "minecraft:entity/wolf/wolf_spotted_angry",
"tame": "minecraft:entity/wolf/wolf_spotted_tame",
"wild": "minecraft:entity/wolf/wolf_spotted"
},
"spawn_conditions": [
{
"condition": {
"type": "minecraft:biome",
"biomes": "#c:has_wolf_variant/spotted"
},
"priority": 1
}
]
}
@@ -0,0 +1,16 @@
{
"assets": {
"angry": "minecraft:entity/wolf/wolf_striped_angry",
"tame": "minecraft:entity/wolf/wolf_striped_tame",
"wild": "minecraft:entity/wolf/wolf_striped"
},
"spawn_conditions": [
{
"condition": {
"type": "minecraft:biome",
"biomes": "#c:has_wolf_variant/striped"
},
"priority": 1
}
]
}
@@ -0,0 +1,16 @@
{
"assets": {
"angry": "minecraft:entity/wolf/wolf_woods_angry",
"tame": "minecraft:entity/wolf/wolf_woods_tame",
"wild": "minecraft:entity/wolf/wolf_woods"
},
"spawn_conditions": [
{
"condition": {
"type": "minecraft:biome",
"biomes": "#c:has_wolf_variant/woods"
},
"priority": 1
}
]
}
@@ -9,7 +9,6 @@
"access.StateAccessor",
"access.StructureAccessorAccessor",
"access.VillagerTypeAccessor",
"fix.BeeMoveGoalsUnsynchronizedRandomAccessFix",
"fix.NetherFossilOptimization",
"implementations.compat.GenerationSettingsFloraFeaturesMixin",
"implementations.terra.BiomeMixin",
@@ -7,6 +7,7 @@ dependencies {
shadedApi(project(":common:implementation:base"))
compileOnly("net.fabricmc:sponge-mixin:${Versions.Mod.mixin}")
compileOnly("io.github.llamalad7:mixinextras-common:${Versions.Mod.mixinExtras}")
annotationProcessor("net.fabricmc:sponge-mixin:${Versions.Mod.mixin}")
annotationProcessor("dev.architectury:architectury-loom:${Versions.Mod.architecuryLoom}")
@@ -18,6 +19,7 @@ dependencies {
modImplementation("org.incendo", "cloud-fabric", Versions.Fabric.cloud) {
exclude("net.fabricmc")
exclude("net.fabricmc.fabric-api")
exclude("me.lucko", "fabric-permissions-api")
}
}
@@ -45,7 +45,7 @@ public abstract class LifecyclePlatform extends ModPlatform {
public LifecyclePlatform() {
generationThreads = getGenerationThreadsWithReflection("com.ishland.c2me.base.common.GlobalExecutors", "GLOBAL_EXECUTOR_PARALLELISM", "C2ME");
if (generationThreads == 0) {
generationThreads = getGenerationThreadsWithReflection("ca.spottedleaf.moonrise.common.util.MoonriseCommon", "WORKER_THREADS", "Moonrise");
generationThreads = getMoonriseGenerationThreadsWithReflection();
} if (generationThreads == 0) {
generationThreads = 1;
}
@@ -107,7 +107,7 @@ public abstract class LifecyclePlatform extends ModPlatform {
super.platformAddon().forEach(addons::add);
String mcVersion = MinecraftVersion.CURRENT.getName();
String mcVersion = MinecraftVersion.CURRENT.name();
try {
addons.add(new EphemeralAddon(Versions.parseVersion(mcVersion), "minecraft"));
} catch(ParseException e) {
@@ -1,27 +0,0 @@
package com.dfsek.terra.lifecycle.mixin.lifecycle;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.mod.CommonPlatform;
import com.dfsek.terra.mod.ModPlatform;
import net.minecraft.client.gui.screen.world.CreateWorldScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static com.dfsek.terra.lifecycle.util.LifecycleUtil.initialized;
@Mixin(CreateWorldScreen.class)
public class CreateWorldScreenMixin {
@Inject(method = "onCloseScreen()V", at = @At("HEAD"))
public void onClose(CallbackInfo ci) {
ModPlatform platform = CommonPlatform.get();
platform.getRawConfigRegistry().clear();
initialized = false;
}
}
@@ -19,8 +19,6 @@ import java.net.Proxy;
import com.dfsek.terra.lifecycle.LifecyclePlatform;
import static com.dfsek.terra.lifecycle.util.LifecycleUtil.initialized;
@Mixin(MinecraftServer.class)
public class MinecraftServerMixin {
@@ -34,11 +32,4 @@ public class MinecraftServerMixin {
WorldGenerationProgressListenerFactory worldGenerationProgressListenerFactory, CallbackInfo ci) {
LifecyclePlatform.setServer((MinecraftServer) (Object) this);
}
@Inject(method = "shutdown()V", at = @At("RETURN"))
private void injectShutdown(CallbackInfo ci) {
ModPlatform platform = CommonPlatform.get();
platform.getRawConfigRegistry().clear();
initialized = false;
}
}
@@ -1,5 +1,8 @@
package com.dfsek.terra.lifecycle.mixin.lifecycle;
import com.dfsek.terra.mod.CommonPlatform;
import com.dfsek.terra.mod.ModPlatform;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.registry.MutableRegistry;
import net.minecraft.registry.Registry;
@@ -7,6 +10,7 @@ import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryLoader;
import net.minecraft.registry.RegistryLoader.Loader;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.source.MultiNoiseBiomeSourceParameterList;
import net.minecraft.world.dimension.DimensionType;
@@ -18,18 +22,33 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Coerce;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import com.llamalad7.mixinextras.sugar.Local;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Coerce;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryLoader;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.resource.ResourceManager;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import com.dfsek.terra.lifecycle.LifecyclePlatform;
import com.dfsek.terra.lifecycle.util.LifecycleUtil;
import com.dfsek.terra.lifecycle.util.RegistryHack;
import static com.dfsek.terra.lifecycle.util.LifecycleUtil.initialized;
@Mixin(RegistryLoader.class)
public class RegistryLoaderMixin {
@@ -38,31 +57,39 @@ public class RegistryLoaderMixin {
@Final
private static Logger LOGGER;
@Redirect(
@Unique
private static final AtomicBoolean LOADING_DYNAMIC_REGISTRIES = new AtomicBoolean(false);
@Inject(method = "loadFromResource(Lnet/minecraft/resource/ResourceManager;Ljava/util/List;Ljava/util/List;)Lnet/minecraft/registry/DynamicRegistryManager$Immutable;", at = @At("HEAD"))
private static void loadFromResources(ResourceManager resourceManager, List<RegistryWrapper.Impl<?>> registries, List<RegistryLoader.Entry<?>> entries, CallbackInfoReturnable<DynamicRegistryManager.Immutable> cir) {
LOADING_DYNAMIC_REGISTRIES.set(entries.stream().anyMatch(entry -> entry.key() == RegistryKeys.BIOME));
}
@Inject(
method = "load(Lnet/minecraft/registry/RegistryLoader$RegistryLoadable;Ljava/util/List;Ljava/util/List;)Lnet/minecraft/registry/DynamicRegistryManager$Immutable;",
at = @At(
value = "INVOKE",
target = "Ljava/util/List;forEach(Ljava/util/function/Consumer;)V",
ordinal = 1 // we want right after the first forEach
)
ordinal = 1
)
)
private static void grabManager(List<RegistryLoader.Loader<?>> instance, Consumer<? super Loader<?>> consumer) {
if(!initialized) {
MutableRegistry<Biome> biomes = extractRegistry(instance, RegistryKeys.BIOME).orElseThrow();
MutableRegistry<DimensionType> dimensionTypes = extractRegistry(instance, RegistryKeys.DIMENSION_TYPE).orElseThrow();
MutableRegistry<WorldPreset> worldPresets = extractRegistry(instance, RegistryKeys.WORLD_PRESET).orElseThrow();
MutableRegistry<ChunkGeneratorSettings> chunkGeneratorSettings = extractRegistry(instance,
private static void beforeFreeze(@Coerce Object loadable, List<RegistryWrapper.Impl<?>> wrappers, List<RegistryLoader.Entry<?>> entries, CallbackInfoReturnable<DynamicRegistryManager.Immutable> cir, @Local(ordinal = 2) List<RegistryLoader.Loader<?>> registriesList) {
if (LOADING_DYNAMIC_REGISTRIES.getAndSet(false)) {
ModPlatform platform = CommonPlatform.get();
platform.getRawConfigRegistry().clear();
MutableRegistry<Biome> biomes = extractRegistry(registriesList, RegistryKeys.BIOME).orElseThrow();
MutableRegistry<DimensionType> dimensionTypes = extractRegistry(registriesList, RegistryKeys.DIMENSION_TYPE).orElseThrow();
MutableRegistry<WorldPreset> worldPresets = extractRegistry(registriesList, RegistryKeys.WORLD_PRESET).orElseThrow();
MutableRegistry<ChunkGeneratorSettings> chunkGeneratorSettings = extractRegistry(registriesList,
RegistryKeys.CHUNK_GENERATOR_SETTINGS).orElseThrow();
MutableRegistry<MultiNoiseBiomeSourceParameterList> multiNoiseBiomeSourceParameterLists = extractRegistry(instance,
MutableRegistry<MultiNoiseBiomeSourceParameterList> multiNoiseBiomeSourceParameterLists = extractRegistry(registriesList,
RegistryKeys.MULTI_NOISE_BIOME_SOURCE_PARAMETER_LIST).orElseThrow();
MutableRegistry<Enchantment> enchantments = extractRegistry(instance, RegistryKeys.ENCHANTMENT).orElseThrow();
MutableRegistry<Enchantment> enchantments = extractRegistry(registriesList, RegistryKeys.ENCHANTMENT).orElseThrow();
LifecyclePlatform.setRegistries(biomes, dimensionTypes, chunkGeneratorSettings, multiNoiseBiomeSourceParameterLists,
enchantments);
LifecycleUtil.initialize(biomes, worldPresets);
initialized = true;
}
instance.forEach(consumer);
}
@Unique
@@ -12,8 +12,6 @@ import com.dfsek.terra.mod.CommonPlatform;
public final class LifecycleUtil {
public static boolean initialized = false;
private LifecycleUtil() {
}
@@ -12,9 +12,6 @@
"lifecycle.RegistryLoaderMixin",
"lifecycle.SaveLoadingMixin"
],
"client": [
"lifecycle.CreateWorldScreenMixin"
],
"server": [
],
"injectors": {
+6
View File
@@ -26,6 +26,12 @@ include(":platforms:minestom:example")
pluginManagement {
repositories {
gradlePluginPortal()
maven("https://maven.solo-studios.ca/releases") {
name = "Solo Studios"
}
maven("https://maven.solo-studios.ca/snapshots") {
name = "Solo Studios"
}
maven("https://maven.fabricmc.net") {
name = "Fabric Maven"
}