Compare commits

..

47 Commits

Author SHA1 Message Date
OakLoaf c282e55f90 Adjusted paper dependency 2025-10-13 12:16:43 +01:00
OakLoaf 8b62badbdb Moved nms packages directly into the nms gradle module 2025-10-13 10:49:06 +01:00
OakLoaf 8bceb255c0 Corrected version formatting in supported versions list 2025-10-13 10:40:40 +01:00
OakLoaf ad80769d67 Removed version specific bindings 2025-10-12 22:48:41 +01:00
Zoë Gidiere c3d26527a7 parallel pack loading 2025-10-09 17:55:29 -06:00
Zoë Gidiere 1fe56335c8 Remove bufferedimage 2025-10-09 17:38:08 -06:00
Zoë Gidiere 3b377d91ee fix concurrency issues in openregistryimpl 2025-10-09 17:34:06 -06:00
Zoë Gidiere d640b49ded Merge pull request #533 from everbuild-org/fix/minestom-platform-fixes
Minestom 1.21.8/9/10 & Metapack support
2025-10-07 23:49:46 -06:00
Zoë Gidiere ecbfd1740c Fabric 1.21.10 2025-10-07 17:55:37 -06:00
Zoe Gidiere dc5952add7 WIP 1.21.10 2025-10-07 17:15:07 -06:00
Christian Bergschneider 1b6ebeb05f fix: improve particle handling and block state retrieval 2025-10-07 23:32:30 +02:00
Christian Bergschneider 234ff3e49c feat: actually do biome preloading 2025-10-07 23:23:54 +02:00
Christian Bergschneider 243c523b57 feat: pre-add biomes to registry to prevent future modifications 2025-10-07 23:06:58 +02:00
Christian Bergschneider 1700650753 feat: add methods to pack by meta and default meta in TerraMinestomWorldBuilder 2025-10-07 22:54:15 +02:00
Christian Bergschneider 12d2221d49 fix: ignore and warn on snbt on particles 2025-10-07 21:38:49 +02:00
Christian Bergschneider 42e1adfc3a chore: update minestom dependency 2025-10-07 21:38:26 +02:00
Zoë Gidiere 4ff91c9fea Revert "Update gradle"
This reverts commit 81bc51f5a1.
2025-10-07 12:53:36 -06:00
Zoe Gidiere 81bc51f5a1 Update gradle 2025-10-07 11:54:36 -06:00
Zoë Gidiere ac98726f81 Cleanup Fabric BlockState and EntityType Extended implementation 2025-10-06 18:12:42 -06:00
Zoë Gidiere 1d2c6d4294 Synchronize pack loading 2025-10-05 23:58:53 -06:00
Zoë Gidiere 9ca7014344 Entity SNBT Support and Cleanup 2025-10-05 23:50:29 -06:00
Zoë Gidiere 8d153998fa Reformat Code 2025-10-05 21:55:16 -06:00
Zoë Gidiere 2b09ed8fd9 Simplify mixin implementations
Refactors mixin implementations to remove unnecessary casting.

This change improves code readability and reduces redundancy by directly accessing methods and fields within the mixin context, rather than relying on casting to the target class.
2025-10-05 21:51:40 -06:00
Zoë Gidiere 96493ede15 Merge remote-tracking branch 'origin/master' 2025-10-05 20:24:25 -06:00
Zoë Gidiere 48586eb523 Fix SNBT writing 2025-10-05 20:23:54 -06:00
Zoë Gidiere a80b94ad45 Unwrap BlockState in Chunk Gen 2025-10-05 17:03:51 -06:00
Zoë Gidiere 089850d633 Support for SNBT in structures 2025-10-05 17:03:45 -06:00
Zoë Gidiere 42f3c56b71 Extended BlockState API 2025-10-05 16:47:12 -06:00
Zoë Gidiere 874ef56025 Update seismic 2025-10-05 16:44:49 -06:00
Zoë Gidiere 06f04005ea Merge pull request #526 from AllayMC/feat/allay-update
feat: update allay-api and resource files
2025-10-04 13:55:02 -06:00
daoge_cmd 774d076f77 build: enable build for allay platform 2025-10-04 17:21:22 +08:00
daoge_cmd e4561bd48f Merge branch 'master' into feat/allay-update
# Conflicts:
#	platforms/allay/src/main/java/com/dfsek/terra/allay/Mapping.java
#	platforms/allay/src/main/java/com/dfsek/terra/allay/handle/AllayItemHandle.java
2025-10-04 17:19:01 +08:00
daoge_cmd 550a037661 chore: remove unused okaeri maven repo 2025-10-04 17:14:49 +08:00
daoge_cmd 3b25e82a73 feat: use allay-api 0.12.0 2025-10-04 17:14:06 +08:00
Zoë Gidiere 9b3a105672 Fix game metapack loading 2025-10-03 19:07:00 -06:00
Zoë Gidiere 10558b5446 fix typo 2025-10-03 18:24:00 -06:00
Zoë Gidiere 326300bcce update resource logic for metapacks 2025-10-03 18:10:45 -06:00
Zoë Gidiere a7826dec49 add metapacks to default commented ingore list 2025-10-03 17:29:30 -06:00
Zoë Gidiere fd3d1ce830 Change ConstantRage check to only check if greater than 2025-10-03 17:11:12 -06:00
Zoë Gidiere 84a6cd0c26 fix bukkit spawning consistency 2025-10-03 15:49:55 -06:00
Zoë Gidiere d1faac8b96 Pull in remaining packs 2025-10-03 15:27:48 -06:00
Zoë Gidiere de4656d01f new pack name 2025-10-03 14:39:27 -06:00
Zoë Gidiere 6dba2e9394 Use latest OW 2025-10-03 13:59:54 -06:00
Zoë Gidiere 8a8db4a9b8 Merge pull request #445 from PolyhedralDev/dev/7.0-2
Dev/7.0
2025-10-03 01:01:49 -06:00
daoge_cmd 3ef60f4b33 feat: adapt allay api 0.12.0-SHAPSHOT (waiting for 0.12.0 release) 2025-09-30 23:12:12 +08:00
daoge_cmd b7864bb6fb feat: use https://github.com/misode/mcmeta to replace the old je_block_default_states.json file (it's renamed to je_blocks.json now). 2025-08-21 11:51:17 +08:00
daoge_cmd 757ed6ad4d feat: update allay-api and mapping files 2025-08-21 00:11:36 +08:00
93 changed files with 1024 additions and 4026 deletions
+6 -6
View File
@@ -22,11 +22,11 @@ repositories {
dependencies {
//TODO Allow pulling from Versions.kt
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.6")
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.9")
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.4")
implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "2.0.0-beta.18")
implementation("org.ow2.asm", "asm", "9.9")
implementation("org.ow2.asm", "asm-tree", "9.9")
implementation("com.dfsek.tectonic", "common", "4.3.1")
implementation("org.yaml", "snakeyaml", "2.5")
}
@@ -57,15 +57,6 @@ fun Project.configureDependencies() {
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") {
name = "Sonatype Snapshots"
}
maven("https://repo.opencollab.dev/maven-releases/") {
name = "OpenCollab Releases"
}
maven("https://repo.opencollab.dev/maven-snapshots/") {
name = "OpenCollab Snapshots"
}
maven("https://storehouse.okaeri.eu/repository/maven-public/") {
name = "Okaeri"
}
maven("https://repo.onarandombox.com/multiverse-releases") {
name = "onarandombox"
}
+22 -4
View File
@@ -49,9 +49,19 @@ fun Project.configureDistribution() {
doFirst {
try {
file("${buildDir}/resources/main/packs/").deleteRecursively()
file("${buildDir}/resources/main/metapacks/").deleteRecursively()
val overworldPackUrl =
URL("https://github.com/PolyhedralDev/TerraOverworldConfig/releases/download/" + Versions.Terra.overworldConfig + "/Overworld.zip")
val reimagENDPackUrl =
URL("https://github.com/PolyhedralDev/ReimagEND/releases/download/" + Versions.Terra.reimagENDConfig + "/ReimagEND.zip")
val tartarusPackUrl =
URL("https://github.com/PolyhedralDev/Tartarus/releases/download/" + Versions.Terra.tartarusConfig + "/Tartarus.zip")
val defaultPackUrl =
URL("https://github.com/PolyhedralDev/TerraOverworldConfig/releases/download/" + Versions.Terra.overworldConfig + "/default.zip")
downloadPack(defaultPackUrl, project)
URL("https://github.com/PolyhedralDev/DefaultMetapack/releases/download/" + Versions.Terra.defaultConfig + "/default.zip")
downloadPack(overworldPackUrl, project)
downloadPack(reimagENDPackUrl, project)
downloadPack(tartarusPackUrl, project)
downloadPack(defaultPackUrl, project, true)
} catch (_: Exception) {
}
}
@@ -97,6 +107,13 @@ fun Project.configureDistribution() {
resources.computeIfAbsent("packs") { ArrayList() }.add(it.name)
}
val metaPacksDir = File("${project.buildDir}/resources/main/metapacks/")
metaPacksDir.walkTopDown().forEach {
if (it.isDirectory || !it.name.endsWith(".zip")) return@forEach
resources.computeIfAbsent("metapacks") { ArrayList() }.add(it.name)
}
val langDir = File("${project(":common:implementation").buildDir}/resources/main/lang/")
langDir.walkTopDown().forEach {
@@ -164,9 +181,10 @@ fun Project.configureDistribution() {
}
}
fun downloadPack(packUrl: URL, project: Project) {
fun downloadPack(packUrl: URL, project: Project, metapack: Boolean = false) {
val fileName = packUrl.file.substring(packUrl.file.lastIndexOf("/"))
val file = File("${project.buildDir}/resources/main/packs/${fileName}")
val resourceType = if (metapack) "metapacks" else "packs"
val file = File("${project.buildDir}/resources/main/${resourceType}/${fileName}")
file.parentFile.mkdirs()
file.outputStream().write(packUrl.readBytes())
}
+37 -31
View File
@@ -1,36 +1,39 @@
object Versions {
object Terra {
const val overworldConfig = "v1.5.2"
const val overworldConfig = "latest"
const val reimagENDConfig = "latest"
const val tartarusConfig = "latest"
const val defaultConfig = "latest"
}
object Libraries {
const val tectonic = "4.2.1"
const val tectonic = "4.3.1"
const val paralithic = "2.0.1"
const val strata = "1.3.2"
const val seismic = "2.0.4"
const val seismic = "2.1.1"
const val cloud = "2.0.0"
const val caffeine = "3.2.1"
const val caffeine = "3.2.2"
const val slf4j = "2.0.17"
object Internal {
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.1"
const val shadow = "8.3.9"
const val apacheText = "1.14.0"
const val apacheIO = "2.20.0"
const val guava = "33.5.0-jre"
const val asm = "9.9"
const val snakeYml = "2.5"
const val jetBrainsAnnotations = "26.0.2-1"
const val junit = "6.0.0"
const val nbt = "6.1"
}
}
object Fabric {
const val fabricAPI = "0.133.14+${Mod.minecraft}"
const val cloud = "2.0.0-beta.11"
const val fabricAPI = "0.134.1+${Mod.minecraft}"
const val cloud = "2.0.0-beta.13"
}
//
// object Quilt {
@@ -39,14 +42,14 @@ object Versions {
// }
object Mod {
const val mixin = "0.15.5+mixin.0.8.7"
const val mixinExtras = "0.4.1"
const val mixin = "0.16.4+mixin.0.8.7"
const val mixinExtras = "0.5.0"
const val minecraft = "1.21.9"
const val minecraft = "1.21.10"
const val yarn = "$minecraft+build.1"
const val fabricLoader = "0.17.2"
const val architecuryLoom = "1.11.440"
const val architecuryLoom = "1.11.451"
const val architecturyPlugin = "3.4.162"
}
@@ -57,17 +60,17 @@ object Versions {
// }
object Bukkit {
const val minecraft = "1.21.9-rc1-R0.1"
const val paperBuild = "$minecraft-20250930.133904-13"
const val minecraft = "1.21.10"
const val nms = "$minecraft-R0.1"
const val paperBuild = "$nms-20251012.013929-7"
const val paper = paperBuild
const val paperLib = "1.0.8"
const val reflectionRemapper = "0.1.2"
const val reflectionRemapper = "0.1.3"
const val paperDevBundle = paperBuild
const val runPaper = "2.3.1"
const val runPaperMinecraft = "1.21.9"
const val paperWeight = "2.0.0-beta.17"
const val cloud = "2.0.0-beta.11"
const val multiverse = "5.0.2"
const val paperWeight = "2.0.0-beta.19"
const val cloud = "2.0.0-beta.12"
const val multiverse = "5.3.0"
}
//
@@ -78,18 +81,21 @@ object Versions {
// }
//
object CLI {
const val logback = "1.5.18"
const val logback = "1.5.19"
const val picocli = "4.7.7"
}
object Allay {
const val api = "0.4.1"
const val gson = "2.13.1"
const val mappings = "3626653"
const val mappingsGenerator = "366618e"
const val api = "0.12.0"
const val gson = "2.13.2"
const val mappings = "8002ed6"
const val mappingsGenerator = "fd83f41"
const val mcmeta = "b758592"
}
object Minestom {
const val minestom = "1_21_6-a40d7115d4"
const val minestom = "2025.10.04-1.21.8"
}
}
@@ -3,13 +3,13 @@ package com.dfsek.terra.addons.biome.pipeline.image.config.converter.mapping;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.Map;
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
import com.dfsek.terra.addons.image.config.ColorLoader.ColorString;
import com.dfsek.terra.addons.image.converter.mapping.ColorMapping;
import com.dfsek.terra.addons.image.util.MapUtil;
import java.util.Map;
public class DefinedPipelineBiomeColorMappingTemplate implements ObjectTemplate<ColorMapping<PipelineBiome>> {
@@ -7,11 +7,11 @@
package com.dfsek.terra.addons.terrascript.parser.lang.functions;
import java.util.List;
import com.dfsek.terra.addons.terrascript.parser.lang.Returnable;
import com.dfsek.terra.addons.terrascript.tokenizer.Position;
import java.util.List;
public interface FunctionBuilder<T extends Function<?>> {
T build(List<Returnable<?>> argumentList, Position position);
@@ -12,12 +12,13 @@ import java.util.function.Consumer;
import com.dfsek.terra.api.Handle;
import com.dfsek.terra.api.block.BlockType;
import com.dfsek.terra.api.block.state.properties.Property;
import com.dfsek.terra.api.data.Extendable;
/**
* Contains basic data about a {@link BlockType} in the world
*/
public interface BlockState extends Handle {
public interface BlockState extends Handle, Extendable {
/**
* Whether this {@link BlockState} matches another.
@@ -0,0 +1,32 @@
package com.dfsek.terra.api.block.state;
import com.dfsek.terra.api.data.ExtendedData;
public interface BlockStateExtended extends BlockState {
/**
* Gets the BlockData.
*
* @return BlockData of this BlockStateExtended
*/
ExtendedData getData();
/**
* Sets the BlockData.
*
* @param data BlockData to set
*
* @return New BlockStateExtended with the given BlockData
*/
BlockStateExtended setData(ExtendedData data);
/**
* Gets the BlockState.
*
* @return Raw BlockState of this BlockStateExtended
*/
BlockState getState();
@Override
default boolean isExtended() { return true; }
}
@@ -0,0 +1,11 @@
package com.dfsek.terra.api.data;
public interface Extendable {
/**
* Get whether this BlockState is an extended state.
* Extended states are states that contain extra data not normally present in a BlockState.
*
* @return Whether this state is extended.
*/
default boolean isExtended() { return false; }
}
@@ -0,0 +1,8 @@
package com.dfsek.terra.api.data;
import com.dfsek.terra.api.Handle;
public interface ExtendedData extends Handle {
String toString();
}
@@ -8,7 +8,8 @@
package com.dfsek.terra.api.entity;
import com.dfsek.terra.api.Handle;
import com.dfsek.terra.api.data.Extendable;
public interface EntityType extends Handle {
public interface EntityType extends Handle, Extendable {
}
@@ -0,0 +1,32 @@
package com.dfsek.terra.api.entity;
import com.dfsek.terra.api.data.ExtendedData;
public interface EntityTypeExtended extends EntityType {
/**
* Gets the BlockData.
*
* @return BlockData of this EntityTypeExtended
*/
ExtendedData getData();
/**
* Sets the BlockData.
*
* @param data BlockData to set
*
* @return New EntityTypeExtended with the given BlockData
*/
EntityTypeExtended setData(ExtendedData data);
/**
* Gets the EntityType.
*
* @return Raw EntityType of this EntityTypeExtended
*/
EntityType getType();
@Override
default boolean isExtended() { return true; }
}
@@ -7,14 +7,14 @@
package com.dfsek.terra.api.structure.configured;
import org.jetbrains.annotations.ApiStatus.Experimental;
import com.dfsek.terra.api.registry.key.StringIdentifiable;
import com.dfsek.terra.api.structure.Structure;
import com.dfsek.terra.api.structure.StructureSpawn;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.util.range.Range;
import org.jetbrains.annotations.ApiStatus.Experimental;
@Experimental
public interface ConfiguredStructure extends StringIdentifiable {
@@ -18,7 +18,7 @@ public class ConstantRange implements Range {
private int max;
public ConstantRange(int min, int max) {
if(min >= max) throw new IllegalArgumentException("Minimum must not be greater than or equal to maximum!");
if(min > max) throw new IllegalArgumentException("Minimum must not be greater than maximum!");
this.max = max;
this.min = min;
}
@@ -1,68 +0,0 @@
/*
* This file is part of Terra.
*
* Terra is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Terra is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Terra. If not, see <https://www.gnu.org/licenses/>.
*/
package com.dfsek.terra.config.loaders.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 org.jetbrains.annotations.NotNull;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.lang.reflect.AnnotatedType;
import java.nio.file.Files;
import java.util.concurrent.ConcurrentHashMap;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.properties.Properties;
/*
* @deprecated Use the Image and ImageLoader class provided by the library-image addon instead. This is subject to removal in v7.
*/
@Deprecated
public class BufferedImageLoader implements TypeLoader<BufferedImage> {
private final ConfigPack pack;
public BufferedImageLoader(ConfigPack pack) {
this.pack = pack;
if(!pack.getContext().has(ImageCache.class))
pack.getContext().put(new ImageCache(new ConcurrentHashMap<>()));
}
@Override
public BufferedImage load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker)
throws LoadException {
return pack.getContext().get(ImageCache.class).map.computeIfAbsent((String) c, s -> {
try {
return ImageIO.read(Files.newInputStream(pack.getRootPath().resolve(s)));
} catch(IOException e) {
throw new LoadException("Unable to load image", e, depthTracker);
}
});
}
/*
* Cache prevents configs from loading the same image multiple times into memory
*/
private record ImageCache(ConcurrentHashMap<String, BufferedImage> map) implements Properties {
}
}
@@ -33,7 +33,6 @@ import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
@@ -77,7 +76,6 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
import com.dfsek.terra.api.world.chunk.generation.util.provider.ChunkGeneratorProvider;
import com.dfsek.terra.config.loaders.GenericTemplateSupplierLoader;
import com.dfsek.terra.config.loaders.config.BufferedImageLoader;
import com.dfsek.terra.config.preprocessor.MetaListLikePreprocessor;
import com.dfsek.terra.config.preprocessor.MetaMapPreprocessor;
import com.dfsek.terra.config.preprocessor.MetaNumberPreprocessor;
@@ -273,8 +271,7 @@ public class ConfigPackImpl implements ConfigPack {
@Override
public void register(TypeRegistry registry) {
registry.registerLoader(ConfigType.class, configTypeRegistry)
.registerLoader(BufferedImage.class, new BufferedImageLoader(this));
registry.registerLoader(ConfigType.class, configTypeRegistry);
registryMap.forEach(registry::registerLoader);
shortcuts.forEach(registry::registerLoader); // overwrite with delegated shortcuts if present
}
@@ -31,6 +31,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@@ -51,11 +52,11 @@ import com.dfsek.terra.api.util.reflection.TypeKey;
public class OpenRegistryImpl<T> implements OpenRegistry<T> {
private static final Entry<?> NULL = new Entry<>(null);
private final Map<RegistryKey, Entry<T>> objects;
private final ListMultimap<String, Pair<RegistryKey, Entry<T>>> objectIDs = Multimaps.newListMultimap(new HashMap<>(), ArrayList::new);
private final ListMultimap<String, Pair<RegistryKey, Entry<T>>> objectIDs = Multimaps.newListMultimap(new ConcurrentHashMap<>(), ArrayList::new);
private final TypeKey<T> typeKey;
public OpenRegistryImpl(TypeKey<T> typeKey) {
this(new HashMap<>(), typeKey);
this(new ConcurrentHashMap<>(), typeKey);
}
protected OpenRegistryImpl(Map<RegistryKey, Entry<T>> init, TypeKey<T> typeKey) {
@@ -23,6 +23,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Stream;
import com.dfsek.terra.api.Platform;
@@ -41,12 +42,12 @@ public class ConfigRegistry extends OpenRegistryImpl<ConfigPack> {
super(TypeKey.of(ConfigPack.class));
}
public void loadAll(Platform platform) throws IOException, PackLoadFailuresException {
public synchronized void loadAll(Platform platform) throws IOException, PackLoadFailuresException {
Path packsDirectory = platform.getDataFolder().toPath().resolve("packs");
Files.createDirectories(packsDirectory);
List<Exception> failedLoads = new ArrayList<>();
List<Exception> failedLoads = new CopyOnWriteArrayList<>();
try(Stream<Path> packs = Files.list(packsDirectory)) {
packs.forEach(path -> {
packs.parallel().forEach(path -> {
try {
ConfigPack pack = new ConfigPackImpl(path, platform);
registerChecked(pack.getRegistryKey(), pack);
@@ -19,4 +19,5 @@ script:
max-recursion: 1000
ignored-resources:
# - "addons"
# - "packs"
# - "packs"
# - "metapacks"
+4 -4
View File
@@ -2,8 +2,8 @@
## Resource files
Current mapping version: je 1.21.4 to be 1.21.50
Current mapping version: je 1.21.7 to be 1.21.93
- `mapping/biomes.json` and `mapping/items.json` obtain from [GeyserMC/mappings](https://github.com/GeyserMC/mappings).
- `mapping/blocks.json` generated by using [GeyserMC/mappings-generator](https://github.com/GeyserMC/mappings-generator), and it's origin name is `generator_blocks.json`.
- `je_block_default_states.json` converted from [Block state values](https://zh.minecraft.wiki/w/Module:Block_state_values).
- `mapping/biomes.json` and `mapping/items.json` are obtained from [GeyserMC/mappings](https://github.com/GeyserMC/mappings).
- `mapping/blocks.json` is obtained from [GeyserMC/mappings-generator](https://github.com/GeyserMC/mappings-generator) (path: `https://github.com/GeyserMC/mappings-generator/blob/master/new_generator_blocks.json`).
- `je_blocks.json` is obtained from [misode/mcmeta](https://github.com/misode/mcmeta) (path: `https://github.com/misode/mcmeta/blob/<version>-summary/blocks/data.json`).
@@ -15,6 +15,10 @@ val geyserMappings: Configuration by configurations.register("geyserMappings") {
isCanBeConsumed = false
}
val mcmeta: Configuration by configurations.register("mcmeta") {
isCanBeConsumed = false
}
dependencies {
shadedApi(project(":common:implementation:base"))
@@ -24,7 +28,9 @@ dependencies {
geyserMappings("GeyserMC.mappings", "items", Versions.Allay.mappings, ext = "json")
geyserMappings("GeyserMC.mappings", "biomes", Versions.Allay.mappings, ext = "json")
geyserMappings("GeyserMC.mappings-generator", "generator_blocks", Versions.Allay.mappingsGenerator, ext = "json")
geyserMappings("GeyserMC.mappings-generator", "new_generator_blocks", Versions.Allay.mappingsGenerator, ext = "json")
mcmeta("misode.mcmeta", "blocks/data", Versions.Allay.mcmeta, ext = "json")
}
tasks.processResources {
@@ -32,6 +38,9 @@ tasks.processResources {
into("mapping")
// rather jank, but whatever
rename("(?:generator_)?([^-]+)-(.*)\\.json", "$1.json")
rename("(?:new_generator_)?([^-]+)-(.*)\\.json", "$1.json")
}
from(mcmeta) {
rename("data-(.*)\\.json", "je_blocks.json")
}
}
@@ -3,8 +3,8 @@ package com.dfsek.terra.allay;
import com.dfsek.tectonic.api.TypeRegistry;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import org.allaymc.api.registry.Registries;
import org.allaymc.api.server.Server;
import org.allaymc.api.world.biome.BiomeId;
import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -89,6 +89,6 @@ public class AllayPlatform extends AbstractPlatform {
protected AllayBiome parseBiome(String id, DepthTracker depthTracker) throws LoadException {
if(!id.startsWith("minecraft:")) throw new LoadException("Invalid biome identifier " + id, depthTracker);
return new AllayBiome(BiomeId.fromId(Mapping.biomeIdJeToBe(id)));
return new AllayBiome(Registries.BIOMES.getByK1(Mapping.biomeIdJeToBe(id)));
}
}
@@ -1,6 +1,6 @@
package com.dfsek.terra.allay;
import org.allaymc.api.utils.HashUtils;
import org.allaymc.api.utils.hash.HashUtils;
import java.util.Map;
import java.util.TreeMap;
@@ -8,19 +8,17 @@ import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.allaymc.api.block.type.BlockState;
import org.allaymc.api.block.type.BlockStateSafeGetter;
import org.allaymc.api.block.type.BlockStateGetter;
import org.allaymc.api.block.type.BlockTypes;
import org.allaymc.api.item.type.ItemType;
import org.allaymc.api.item.type.ItemTypeSafeGetter;
import org.allaymc.api.item.type.ItemTypeGetter;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -37,11 +35,11 @@ public final class Mapping {
.registerTypeAdapterFactory(new IgnoreFailureTypeAdapterFactory())
.create();
private static final Map<String, Map<String, String>> JE_BLOCK_DEFAULT_PROPERTIES = new Object2ObjectOpenHashMap<>();
private static final Map<BlockState, JeBlockState> BE_BLOCK_STATE_TO_JE = new Object2ObjectOpenHashMap<>();
private static final Map<Integer, BlockState> JE_BLOCK_STATE_HASH_TO_BE = new Int2ObjectOpenHashMap<>();
private static final Map<String, ItemType<?>> JE_ITEM_ID_TO_BE = new Object2ObjectOpenHashMap<>();
private static final Map<String, Integer> JE_BIOME_ID_TO_BE = new Object2IntOpenHashMap<>();
private static final Map<String, Map<String, String>> JE_BLOCK_DEFAULT_PROPERTIES = new HashMap<>();
private static final Map<BlockState, JeBlockState> BE_BLOCK_STATE_TO_JE = new HashMap<>();
private static final Map<Integer, BlockState> JE_BLOCK_STATE_HASH_TO_BE = new HashMap<>();
private static final Map<String, ItemType<?>> JE_ITEM_ID_TO_BE = new HashMap<>();
private static final Map<String, Integer> JE_BIOME_ID_TO_BE = new HashMap<>();
private static final BlockState BE_AIR_STATE = BlockTypes.AIR.getDefaultState();
@@ -124,7 +122,7 @@ public final class Mapping {
Map<String, ItemMapping> mappings = from(stream, new TypeToken<>() {
});
mappings.forEach((javaId, mapping) -> {
ItemType<?> itemType = ItemTypeSafeGetter
ItemType<?> itemType = ItemTypeGetter
.name(mapping.bedrockId())
.meta(mapping.bedrockData())
.itemType();
@@ -160,16 +158,22 @@ public final class Mapping {
return true;
}
@SuppressWarnings("unchecked")
private static boolean initJeBlockDefaultProperties() {
try(InputStream stream = Mapping.class.getClassLoader().getResourceAsStream("je_block_default_states.json")) {
try(InputStream stream = Mapping.class.getClassLoader().getResourceAsStream("je_blocks.json")) {
if(stream == null) {
TerraAllayPlugin.INSTANCE.getPluginLogger().error("je_block_default_states.json not found");
return false;
}
Map<String, Map<String, String>> states = from(stream, new TypeToken<>() {
Map<String, List<Map<String, ?>>> data = from(stream, new TypeToken<>() {
});
JE_BLOCK_DEFAULT_PROPERTIES.putAll(states);
for(var entry : data.entrySet()) {
JE_BLOCK_DEFAULT_PROPERTIES.put(
"minecraft:" + entry.getKey(),
(Map<String, String>) entry.getValue().get(1)
);
}
} catch(IOException e) {
throw new RuntimeException(e);
}
@@ -182,7 +186,7 @@ public final class Mapping {
}
private static BlockState createBeBlockState(BlockMapping.BedrockState state) {
BlockStateSafeGetter.Getter getter = BlockStateSafeGetter.name("minecraft:" + state.bedrockId());
BlockStateGetter.Getter getter = BlockStateGetter.name("minecraft:" + state.bedrockId());
if(state.state() != null) {
convertValueType(state.state()).forEach(getter::property);
}
@@ -1,6 +1,6 @@
package com.dfsek.terra.allay.delegate;
import org.allaymc.api.block.tag.BlockTags;
import org.allaymc.api.block.data.BlockTags;
import org.allaymc.api.block.type.BlockType;
import com.dfsek.terra.allay.Mapping;
@@ -1,7 +1,7 @@
package com.dfsek.terra.allay.delegate;
import org.allaymc.api.block.data.BlockTags;
import org.allaymc.api.block.property.type.BlockPropertyTypes;
import org.allaymc.api.block.tag.BlockTags;
import org.allaymc.api.block.type.BlockTypes;
import org.allaymc.api.world.chunk.Chunk;
import org.jetbrains.annotations.NotNull;
@@ -1,7 +1,7 @@
package com.dfsek.terra.allay.delegate;
import org.allaymc.api.block.property.type.BlockPropertyTypes;
import org.allaymc.api.block.tag.BlockTags;
import org.allaymc.api.block.data.BlockTags;
import org.allaymc.api.block.type.BlockTypes;
import org.allaymc.api.world.chunk.UnsafeChunk;
import org.jetbrains.annotations.NotNull;
@@ -2,7 +2,7 @@ package com.dfsek.terra.allay.delegate;
import com.dfsek.seismic.type.vector.Vector3;
import org.allaymc.api.block.property.type.BlockPropertyTypes;
import org.allaymc.api.block.tag.BlockTags;
import org.allaymc.api.block.data.BlockTags;
import org.allaymc.api.block.type.BlockTypes;
import org.allaymc.api.world.generator.context.OtherChunkAccessibleContext;
@@ -22,7 +22,7 @@ import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
public record AllayServerWorld(AllayGeneratorWrapper allayGeneratorWrapper, Dimension allayDimension) implements ServerWorld {
@Override
public Chunk getChunkAt(int x, int z) {
return new AllayChunk(this, allayDimension.getChunkService().getChunk(x, z));
return new AllayChunk(this, allayDimension.getChunkManager().getChunk(x, z));
}
@Override
@@ -152,11 +152,6 @@ public class AllayGeneratorWrapper implements GeneratorWrapper {
}
return true;
}
@Override
public String getName() {
return "TERRA_NOISER";
}
}
@@ -174,10 +169,5 @@ public class AllayGeneratorWrapper implements GeneratorWrapper {
}
return true;
}
@Override
public String getName() {
return "TERRA_POPULATOR";
}
}
}
@@ -1,7 +1,6 @@
package com.dfsek.terra.allay.handle;
import org.allaymc.api.registry.Registries;
import org.allaymc.api.utils.Identifier;
import java.util.Set;
import java.util.stream.Collectors;
@@ -13,6 +12,8 @@ import com.dfsek.terra.api.handle.ItemHandle;
import com.dfsek.terra.api.inventory.Item;
import com.dfsek.terra.api.inventory.item.Enchantment;
import org.allaymc.api.utils.identifier.Identifier;
/**
* @author daoge_cmd
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -8,7 +8,7 @@ dependencies {
paperweight.paperDevBundle(Versions.Bukkit.paperDevBundle)
shaded(project(":platforms:bukkit:common"))
shaded(project(":platforms:bukkit:nms:v1_21_9"))
shaded(project(":platforms:bukkit:nms"))
shaded("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper)
}
@@ -27,13 +27,13 @@ tasks {
}
runServer {
minecraftVersion(Versions.Bukkit.runPaperMinecraft)
minecraftVersion(Versions.Bukkit.minecraft)
dependsOn(shadowJar)
pluginJars(shadowJar.get().archiveFile)
downloadPlugins {
modrinth("viaversion", "5.3.2")
modrinth("viabackwards", "5.3.2")
modrinth("viaversion", "5.5.0")
modrinth("viabackwards", "5.5.0")
}
}
}
@@ -0,0 +1,54 @@
package com.dfsek.terra.bukkit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.dfsek.terra.bukkit.util.VersionUtil;
import java.util.List;
public interface NMSInitializer {
List<String> SUPPORTED_VERSIONS = List.of("v1.21.9", "v1.21.10");
String MINECRAFT_VERSION = VersionUtil.getMinecraftVersionInfo().toString();
String TERRA_PACKAGE = NMSInitializer.class.getPackageName();
static PlatformImpl init(TerraBukkitPlugin plugin) {
Logger logger = LoggerFactory.getLogger(NMSInitializer.class);
if (!SUPPORTED_VERSIONS.contains(MINECRAFT_VERSION)) {
logger.error("You are running your server on Minecraft version {} which is not supported by this version of Terra.", MINECRAFT_VERSION);
String bypassKey = "IKnowThereAreNoNMSBindingsFor" + MINECRAFT_VERSION.replace(".", "_") + "ButIWillProceedAnyway";
if(System.getProperty(bypassKey) == null) {
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 null;
} else {
logger.error("");
logger.error("");
for(int i = 0; i < 20; i++) {
logger.error("PROCEEDING WITH AN EXISTING TERRA WORLD WILL RESULT IN CORRUPTION!!!");
}
logger.error("");
logger.error("");
logger.error("We will not give you any support for issues that may arise.");
logger.error("Since you enabled the \"{}\" flag, we won't disable Terra. But be warned.", bypassKey);
}
}
return constructPlatform(plugin);
}
private static PlatformImpl constructPlatform(TerraBukkitPlugin plugin) {
try {
Class<?> platformClass = Class.forName(TERRA_PACKAGE + ".nms.NMSPlatform");
return (PlatformImpl) platformClass
.getConstructor(TerraBukkitPlugin.class)
.newInstance(plugin);
} catch(ReflectiveOperationException e) {
throw new RuntimeException("Error initializing NMS bindings. Report this to Terra.", e);
}
}
}
@@ -40,7 +40,6 @@ import com.dfsek.terra.api.event.events.platform.CommandRegistrationEvent;
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper;
import com.dfsek.terra.bukkit.listeners.CommonListener;
import com.dfsek.terra.bukkit.nms.Initializer;
import com.dfsek.terra.bukkit.util.PaperUtil;
import com.dfsek.terra.bukkit.util.VersionUtil;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
@@ -60,7 +59,7 @@ public class TerraBukkitPlugin extends JavaPlugin {
return;
}
platform = Initializer.init(this);
platform = NMSInitializer.init(this);
if(platform == null) {
Bukkit.getPluginManager().disablePlugin(this);
return;
@@ -1,60 +0,0 @@
package com.dfsek.terra.bukkit.nms;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.dfsek.terra.bukkit.PlatformImpl;
import com.dfsek.terra.bukkit.TerraBukkitPlugin;
import com.dfsek.terra.bukkit.util.VersionUtil;
public interface Initializer {
String NMS = VersionUtil.getMinecraftVersionInfo().toString().replace(".", "_");
String TERRA_PACKAGE = Initializer.class.getPackageName();
static PlatformImpl init(TerraBukkitPlugin plugin) {
Logger logger = LoggerFactory.getLogger(Initializer.class);
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";
if(System.getProperty(bypassKey) == null) {
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 null;
} else {
logger.error("");
logger.error("");
for(int i = 0; i < 20; i++) {
logger.error("PROCEEDING WITH AN EXISTING TERRA WORLD WILL RESULT IN CORRUPTION!!!");
}
logger.error("");
logger.error("");
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.");
logger.error("We will not give you any support for issues that may arise.");
logger.error("Since you enabled the \"{}\" flag, we won't disable Terra. But be warned.", bypassKey);
}
}
return platform;
}
private static PlatformImpl constructPlatform(TerraBukkitPlugin plugin) {
try {
Class<?> platformClass = Class.forName(TERRA_PACKAGE + "." + NMS + ".NMSPlatform");
try {
return (PlatformImpl) platformClass
.getConstructor(TerraBukkitPlugin.class)
.newInstance(plugin);
} catch(ReflectiveOperationException e) {
throw new RuntimeException("Error initializing NMS bindings. Report this to Terra.", e);
}
} catch(ClassNotFoundException e) {
return null;
}
}
}
@@ -17,12 +17,12 @@
package com.dfsek.terra.bukkit.util;
import com.dfsek.terra.bukkit.TerraBukkitPlugin;
import io.papermc.lib.PaperLib;
import java.util.concurrent.TimeUnit;
import com.dfsek.terra.bukkit.TerraBukkitPlugin;
import static io.papermc.lib.PaperLib.suggestPaper;
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_9;
package com.dfsek.terra.bukkit.nms;
import net.minecraft.core.Holder;
import net.minecraft.core.Holder.Reference;
@@ -25,7 +25,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import com.dfsek.terra.bukkit.nms.v1_21_9.config.VanillaBiomeProperties;
import com.dfsek.terra.bukkit.nms.config.VanillaBiomeProperties;
import com.dfsek.terra.bukkit.world.BukkitBiomeInfo;
import com.dfsek.terra.bukkit.world.BukkitPlatformBiome;
import com.dfsek.terra.registry.master.ConfigRegistry;
@@ -1,11 +1,11 @@
package com.dfsek.terra.bukkit.nms.v1_21_9;
package com.dfsek.terra.bukkit.nms;
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_9.config.VanillaBiomeProperties;
import com.dfsek.terra.bukkit.nms.config.VanillaBiomeProperties;
public class NMSAddon extends BukkitAddon {
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_9;
package com.dfsek.terra.bukkit.nms;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.biome.Biome;
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_9;
package com.dfsek.terra.bukkit.nms;
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_9.config.VanillaBiomeProperties;
import com.dfsek.terra.bukkit.nms.config.VanillaBiomeProperties;
public class NMSBiomeInjector {
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_9;
package com.dfsek.terra.bukkit.nms;
import com.mojang.serialization.MapCodec;
import net.minecraft.core.Holder;
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_9;
package com.dfsek.terra.bukkit.nms;
import com.mojang.serialization.MapCodec;
import net.minecraft.core.BlockPos;
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_9;
package com.dfsek.terra.bukkit.nms;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ServerLevel;
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_9;
package com.dfsek.terra.bukkit.nms;
import com.dfsek.tectonic.api.TypeRegistry;
import com.dfsek.tectonic.api.exception.LoadException;
@@ -27,17 +27,17 @@ 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_9.config.BiomeAdditionsSoundTemplate;
import com.dfsek.terra.bukkit.nms.v1_21_9.config.BiomeMoodSoundTemplate;
import com.dfsek.terra.bukkit.nms.v1_21_9.config.BiomeParticleConfigTemplate;
import com.dfsek.terra.bukkit.nms.v1_21_9.config.EntityTypeTemplate;
import com.dfsek.terra.bukkit.nms.v1_21_9.config.MusicSoundTemplate;
import com.dfsek.terra.bukkit.nms.v1_21_9.config.SoundEventTemplate;
import com.dfsek.terra.bukkit.nms.v1_21_9.config.SpawnCostConfig;
import com.dfsek.terra.bukkit.nms.v1_21_9.config.SpawnEntryConfig;
import com.dfsek.terra.bukkit.nms.v1_21_9.config.SpawnSettingsTemplate;
import com.dfsek.terra.bukkit.nms.v1_21_9.config.SpawnTypeConfig;
import com.dfsek.terra.bukkit.nms.v1_21_9.config.VillagerTypeTemplate;
import com.dfsek.terra.bukkit.nms.config.BiomeAdditionsSoundTemplate;
import com.dfsek.terra.bukkit.nms.config.BiomeMoodSoundTemplate;
import com.dfsek.terra.bukkit.nms.config.BiomeParticleConfigTemplate;
import com.dfsek.terra.bukkit.nms.config.EntityTypeTemplate;
import com.dfsek.terra.bukkit.nms.config.MusicSoundTemplate;
import com.dfsek.terra.bukkit.nms.config.SoundEventTemplate;
import com.dfsek.terra.bukkit.nms.config.SpawnCostConfig;
import com.dfsek.terra.bukkit.nms.config.SpawnEntryConfig;
import com.dfsek.terra.bukkit.nms.config.SpawnSettingsTemplate;
import com.dfsek.terra.bukkit.nms.config.SpawnTypeConfig;
import com.dfsek.terra.bukkit.nms.config.VillagerTypeTemplate;
public class NMSPlatform extends PlatformImpl {
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_9;
package com.dfsek.terra.bukkit.nms;
import net.minecraft.world.level.LevelHeightAccessor;
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_9;
package com.dfsek.terra.bukkit.nms;
import net.minecraft.core.Holder;
import net.minecraft.core.Holder.Reference;
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_9;
package com.dfsek.terra.bukkit.nms;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_9.config;
package com.dfsek.terra.bukkit.nms.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_9.config;
package com.dfsek.terra.bukkit.nms.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_9.config;
package com.dfsek.terra.bukkit.nms.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_9.config;
package com.dfsek.terra.bukkit.nms.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_9.config;
package com.dfsek.terra.bukkit.nms.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_9.config;
package com.dfsek.terra.bukkit.nms.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_9.config;
package com.dfsek.terra.bukkit.nms.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_9.config;
package com.dfsek.terra.bukkit.nms.config;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
@@ -6,6 +6,8 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData;
import com.dfsek.terra.api.util.range.Range;
public class SpawnEntryConfig implements ObjectTemplate<SpawnEntryConfig> {
@Value("type")
@@ -16,20 +18,16 @@ public class SpawnEntryConfig implements ObjectTemplate<SpawnEntryConfig> {
@Default
private Integer weight = null;
@Value("min-group-size")
@Value("group-size")
@Default
private Integer minGroupSize = null;
@Value("max-group-size")
@Default
private Integer maxGroupSize = null;
private Range groupSize = null;
public Integer getWeight() {
return weight;
}
public SpawnerData getSpawnEntry() {
return new SpawnerData(type, minGroupSize, maxGroupSize);
return new SpawnerData(type, groupSize.getMin(), groupSize.getMax());
}
@Override
@@ -1,4 +1,4 @@
package com.dfsek.terra.bukkit.nms.v1_21_9.config;
package com.dfsek.terra.bukkit.nms.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_9.config;
package com.dfsek.terra.bukkit.nms.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_9.config;
package com.dfsek.terra.bukkit.nms.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_9.config;
package com.dfsek.terra.bukkit.nms.config;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
@@ -35,7 +35,7 @@
"depends": {
"fabricloader": ">=0.16.10",
"java": ">=21",
"minecraft": "1.21.9",
"minecraft": "1.21.10",
"fabric": "*"
}
}
+1 -1
View File
@@ -3,7 +3,7 @@ dependencies {
shadedApi("com.github.ben-manes.caffeine", "caffeine", Versions.Libraries.caffeine)
shadedImplementation("com.google.guava", "guava", Versions.Libraries.Internal.guava)
compileOnly("net.minestom", "minestom-snapshots", Versions.Minestom.minestom)
compileOnly("net.minestom", "minestom", Versions.Minestom.minestom)
}
tasks.named("jar") {
+1 -1
View File
@@ -7,7 +7,7 @@ val javaMainClass = "com.dfsek.terra.minestom.TerraMinestomExample"
dependencies {
shadedApi(project(":platforms:minestom"))
implementation("net.minestom", "minestom-snapshots", Versions.Minestom.minestom)
implementation("net.minestom", "minestom", Versions.Minestom.minestom)
implementation("org.slf4j", "slf4j-simple", Versions.Libraries.slf4j)
}
@@ -9,6 +9,7 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
import net.minestom.server.event.player.PlayerSpawnEvent;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.LightingChunk;
import net.minestom.server.world.DimensionType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,7 +44,7 @@ public class TerraMinestomExample {
public void attachTerra() {
world = platform.worldBuilder(instance)
.defaultPack()
.packByDefaultMeta(DimensionType.OVERWORLD)
.attach();
}
@@ -2,6 +2,12 @@ package com.dfsek.terra.minestom;
import com.dfsek.tectonic.api.TypeRegistry;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import com.dfsek.terra.minestom.api.BiomeFactory;
import com.dfsek.terra.minestom.biome.MinestomUserDefinedBiomeFactory;
import com.dfsek.terra.minestom.biome.MinestomUserDefinedBiomePool;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.util.RGBLike;
import net.minestom.server.MinecraftServer;
@@ -9,6 +15,7 @@ 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.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,19 +52,22 @@ public final class TerraMinestomPlatform extends AbstractPlatform {
private final ItemHandle itemHandle;
private final TypeLoader<PlatformBiome> biomeTypeLoader;
private final ArrayList<BaseAddon> platformAddons = new ArrayList<>(List.of(new MinestomAddon(this)));
private final MinestomUserDefinedBiomePool biomePool;
public TerraMinestomPlatform(WorldHandle worldHandle, ItemHandle itemHandle, TypeLoader<PlatformBiome> biomeTypeLoader,
BaseAddon... extraAddons) {
BiomeFactory biomeFactory, BaseAddon... extraAddons) {
this.worldHandle = worldHandle;
this.itemHandle = itemHandle;
this.biomeTypeLoader = biomeTypeLoader;
this.biomePool = new MinestomUserDefinedBiomePool(biomeFactory);
this.platformAddons.addAll(List.of(extraAddons));
load();
getEventManager().callEvent(new PlatformInitializationEvent());
initializeRegistry(); // Needs to be called before minecraft server bind
}
public TerraMinestomPlatform() {
this(new MinestomWorldHandle(), new MinestomItemHandle(), new MinestomBiomeLoader());
this(new MinestomWorldHandle(), new MinestomItemHandle(), new MinestomBiomeLoader(), new MinestomUserDefinedBiomeFactory());
}
@Override
@@ -94,6 +104,10 @@ public final class TerraMinestomPlatform extends AbstractPlatform {
return succeed;
}
public void initializeRegistry() {
getRawConfigRegistry()
.forEach(pack -> biomePool.preloadBiomes(pack, pack.getBiomeProvider().getBiomes()));
}
@Override
public @NotNull WorldHandle getWorldHandle() {
@@ -125,10 +139,62 @@ public final class TerraMinestomPlatform extends AbstractPlatform {
}
public TerraMinestomWorldBuilder worldBuilder(Instance instance) {
return new TerraMinestomWorldBuilder(this, instance);
return new TerraMinestomWorldBuilder(this, instance, biomePool);
}
public TerraMinestomWorldBuilder worldBuilder() {
return new TerraMinestomWorldBuilder(this, MinecraftServer.getInstanceManager().createInstanceContainer());
return worldBuilder(MinecraftServer.getInstanceManager().createInstanceContainer());
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private @Nullable WorldHandle worldHandle;
private @Nullable ItemHandle itemHandle;
private @Nullable TypeLoader<PlatformBiome> biomeTypeLoader;
private @Nullable BiomeFactory biomeFactory;
private final List<BaseAddon> platformAddons = new ArrayList<>();
public Builder worldHandle(@Nullable WorldHandle worldHandle) {
this.worldHandle = worldHandle;
return this;
}
public Builder itemHandle(@Nullable ItemHandle itemHandle) {
this.itemHandle = itemHandle;
return this;
}
public Builder biomeTypeLoader(@Nullable TypeLoader<PlatformBiome> biomeTypeLoader) {
this.biomeTypeLoader = biomeTypeLoader;
return this;
}
public Builder addPlatformAddon(BaseAddon addon) {
this.platformAddons.add(addon);
return this;
}
public Builder biomeFactory(BiomeFactory biomeFactory) {
this.biomeFactory = biomeFactory;
return this;
}
public TerraMinestomPlatform build() {
if(worldHandle == null) worldHandle = new MinestomWorldHandle();
if(itemHandle == null) itemHandle = new MinestomItemHandle();
if(biomeTypeLoader == null) biomeTypeLoader = new MinestomBiomeLoader();
if(biomeFactory == null) biomeFactory = new MinestomUserDefinedBiomeFactory();
return new TerraMinestomPlatform(
worldHandle,
itemHandle,
biomeTypeLoader,
biomeFactory,
platformAddons.toArray(new BaseAddon[0])
);
}
}
}
@@ -2,6 +2,8 @@ package com.dfsek.terra.minestom.addon;
import ca.solostudios.strata.Versions;
import ca.solostudios.strata.version.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
@@ -10,9 +12,6 @@ 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);
@@ -1,5 +1,7 @@
package com.dfsek.terra.minestom.api;
import com.dfsek.terra.minestom.biome.MinestomUserDefinedBiomePool;
import net.minestom.server.instance.Instance;
import java.util.Random;
@@ -8,25 +10,29 @@ import java.util.function.Function;
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.registry.RegistryKey;
import net.minestom.server.world.DimensionType;
import org.jspecify.annotations.NonNull;
public class TerraMinestomWorldBuilder {
private final TerraMinestomPlatform platform;
private final Instance instance;
private final MinestomUserDefinedBiomePool biomePool;
private ConfigPack pack;
private long seed = new Random().nextLong();
private EntityFactory entityFactory = new DefaultEntityFactory();
private BlockEntityFactory blockEntityFactory;
private BiomeFactory biomeFactory = new MinestomUserDefinedBiomeFactory();
public TerraMinestomWorldBuilder(TerraMinestomPlatform platform, Instance instance) {
public TerraMinestomWorldBuilder(TerraMinestomPlatform platform, Instance instance, MinestomUserDefinedBiomePool biomePool) {
this.platform = platform;
this.instance = instance;
this.blockEntityFactory = new DefaultBlockEntityFactory(instance);
this.biomePool = biomePool;
}
public TerraMinestomWorldBuilder pack(ConfigPack pack) {
@@ -36,10 +42,22 @@ public class TerraMinestomWorldBuilder {
public TerraMinestomWorldBuilder packById(String id) {
this.pack = platform.getConfigRegistry().getByID(id).orElseThrow();
return this;
}
public TerraMinestomWorldBuilder packByMeta(String metaPack, RegistryKey<@NonNull DimensionType> dimensionType) {
this.pack = platform.getMetaConfigRegistry()
.getByID(metaPack)
.orElseThrow(() -> new RuntimeException("MetaPack " + metaPack + " could not be found"))
.packs()
.get(dimensionType.key().asString());
return this;
}
public TerraMinestomWorldBuilder packByDefaultMeta(RegistryKey<@NonNull DimensionType> dimensionType) {
return packByMeta("DEFAULT", dimensionType);
}
public TerraMinestomWorldBuilder findPack(Function<CheckedRegistry<ConfigPack>, ConfigPack> fn) {
this.pack = fn.apply(platform.getConfigRegistry());
return this;
@@ -64,12 +82,7 @@ public class TerraMinestomWorldBuilder {
return this;
}
public TerraMinestomWorldBuilder biomeFactory(BiomeFactory factory) {
this.biomeFactory = factory;
return this;
}
public TerraMinestomWorld attach() {
return new TerraMinestomWorld(platform, instance, pack, seed, entityFactory, blockEntityFactory, biomeFactory);
return new TerraMinestomWorld(platform, instance, pack, seed, entityFactory, blockEntityFactory, biomePool);
}
}
@@ -4,6 +4,9 @@ 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 com.dfsek.terra.api.world.biome.PlatformBiome;
import net.kyori.adventure.key.Key;
import net.minestom.server.registry.RegistryKey;
import org.intellij.lang.annotations.Subst;
@@ -11,8 +14,6 @@ import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
import com.dfsek.terra.api.world.biome.PlatformBiome;
public class MinestomBiomeLoader implements TypeLoader<PlatformBiome> {
@Override
@@ -12,14 +12,12 @@ public class MinestomUserDefinedBiomePool {
private final IdentityHashMap<Biome, UserDefinedBiome> biomes = new IdentityHashMap<>();
private final HashSet<String> createdBiomes = new HashSet<>();
private final BiomeFactory factory;
private final ConfigPack configPack;
public MinestomUserDefinedBiomePool(ConfigPack configPack, BiomeFactory factory) {
this.configPack = configPack;
public MinestomUserDefinedBiomePool(BiomeFactory factory) {
this.factory = factory;
}
public UserDefinedBiome getBiome(Biome source) {
public UserDefinedBiome getBiome(ConfigPack configPack, Biome source) {
UserDefinedBiome userDefinedBiome = biomes.get(source);
if(userDefinedBiome != null) return userDefinedBiome;
userDefinedBiome = factory.create(configPack, source);
@@ -28,7 +26,7 @@ public class MinestomUserDefinedBiomePool {
return userDefinedBiome;
}
public void preloadBiomes(Iterable<Biome> biomesToLoad) {
public void preloadBiomes(ConfigPack configPack, Iterable<Biome> biomesToLoad) {
biomesToLoad
.forEach(biome -> {
if(!this.createdBiomes.contains(biome.getID())) {
@@ -13,6 +13,7 @@ import com.dfsek.terra.api.block.state.properties.Property;
public class MinestomBlockState implements BlockState {
private final Block block;
public static final MinestomBlockState AIR = new MinestomBlockState(Block.AIR);
public MinestomBlockState(Block block) {
if(block == null) {
@@ -32,7 +32,9 @@ public class CachedChunk implements ProtoChunk {
public void setBlock(int x, int y, int z, @NotNull BlockState blockState) {
Block block = (Block) blockState.getHandle();
if(block == null) return;
blocks[getIndex(x, y, z)] = block;
int index = getIndex(x, y, z);
if (index > blocks.length || index < 0) return;
blocks[index] = block;
}
private int getIndex(int x, int y, int z) {
@@ -42,7 +44,9 @@ public class CachedChunk implements ProtoChunk {
@Override
public @NotNull BlockState getBlock(int x, int y, int z) {
return new MinestomBlockState(blocks[getIndex(x, y, z)]);
int index = getIndex(x, y, z);
if (index > blocks.length || index < 0) return MinestomBlockState.AIR;
return new MinestomBlockState(blocks[index]);
}
@Override
@@ -3,8 +3,18 @@ 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.nbt.BinaryTagIO;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.kyori.adventure.nbt.TagStringIO;
import net.minestom.server.MinecraftServer;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.arguments.minecraft.registry.ArgumentParticle;
import net.minestom.server.particle.Particle;
import net.minestom.server.world.biome.BiomeEffects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class BiomeParticleConfigTemplate implements ObjectTemplate<BiomeEffects.Particle> {
@@ -22,9 +32,16 @@ public class BiomeParticleConfigTemplate implements ObjectTemplate<BiomeEffects.
return null;
}
String[] parts = particle.split("\\{");
Particle parsedParticle = Particle.fromKey(parts[0]);
if (parts.length > 1) {
LoggerFactory.getLogger(BiomeParticleConfigTemplate.class).warn("Particle {} has additional data, particle will be ignored.", particle);
return null;
}
return new BiomeEffects.Particle(
probability,
Particle.fromKey(particle)
parsedParticle
);
}
}
@@ -1,10 +1,10 @@
package com.dfsek.terra.minestom.entity;
import com.dfsek.terra.minestom.api.EntityFactory;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import com.dfsek.terra.minestom.api.EntityFactory;
public class DefaultEntityFactory implements EntityFactory {
@Override
@@ -40,7 +40,6 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe
this.biomePool = biomePool;
this.biomeProvider = pack.getBiomeProvider();
this.cache = new GeneratedChunkCache(world.getDimensionType(), generator, world, biomeProvider);
preloadBiomes();
}
public ChunkGenerator getGenerator() {
@@ -73,6 +72,7 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe
if(relativeX % 4 == 0 && relativeY % 4 == 0 && relativeZ % 4 == 0) {
UserDefinedBiome userDefinedBiome = biomePool.getBiome(
pack,
biomeProvider.getBiome(absoluteX, absoluteY, absoluteZ, world.getSeed())
);
@@ -101,11 +101,6 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe
this.pack = pack;
this.generator = pack.getGeneratorProvider().newInstance(pack);
this.biomePool.invalidate();
preloadBiomes();
}
private void preloadBiomes() {
this.biomePool.preloadBiomes(world.getBiomeProvider().getBiomes());
}
public void displayStats() {
@@ -44,7 +44,7 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties {
long seed,
EntityFactory entityFactory,
BlockEntityFactory blockEntityFactory,
BiomeFactory factory
MinestomUserDefinedBiomePool biomePool
) {
this.instance = instance;
this.pack = pack;
@@ -57,7 +57,7 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties {
pack.getGeneratorProvider().newInstance(pack),
this,
pack,
new MinestomUserDefinedBiomePool(pack, factory)
biomePool
);
this.entityFactory = entityFactory;
@@ -66,7 +66,8 @@ public abstract class ModPlatform extends AbstractPlatform {
});
getRawConfigRegistry()
.forEach(pack -> {
PresetUtil.createDefault(pack, this, configPacksInMetaPack.contains(pack.getID())).apply(registerFunction);
boolean packInMetapack = configPacksInMetaPack.contains(pack.getID());
PresetUtil.createDefault(pack, this, packInMetapack, packInMetapack).apply(registerFunction);
});
}
@@ -20,6 +20,7 @@ package com.dfsek.terra.mod.generation;
import com.mojang.serialization.MapCodec;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.command.argument.BlockStateArgument;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.Util;
import net.minecraft.util.math.BlockPos;
@@ -47,6 +48,7 @@ import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import com.dfsek.terra.api.block.state.BlockStateExtended;
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;
@@ -133,9 +135,18 @@ public class MinecraftChunkGeneratorWrapper extends net.minecraft.world.gen.chun
for(int y = world.getMaxHeight(); y >= world.getMinHeight(); y--) {
double noise = structureWeightSampler.sample(new UnblendedNoisePos(x + xi, y, z + zi));
if(noise > threshold) {
chunk.setBlockState(new BlockPos(x, y, z), (BlockState) delegate
.getPalette(x + xi, y, z + zi, world, biomeProvider)
.get(depth, x + xi, y, z + zi, world.getSeed()), 0);
com.dfsek.terra.api.block.state.BlockState data = delegate.getPalette(x + xi, y, z + zi, world, biomeProvider).get(
depth, x + xi, y, z + zi, world.getSeed());
BlockPos blockPos = new BlockPos(x, y, z);
boolean isExtended = data.isExtended() && data.getClass().equals(BlockStateArgument.class);
if(isExtended) {
BlockStateExtended blockStateExtended = (BlockStateExtended) data;
net.minecraft.block.BlockState blockState = (net.minecraft.block.BlockState) blockStateExtended.getState();
chunk.setBlockState(blockPos, blockState, 0);
} else {
chunk.setBlockState(blockPos, (net.minecraft.block.BlockState) data, 0);
}
depth++;
} else if(noise < airThreshold) {
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.getDefaultState(), 0);
@@ -183,9 +194,12 @@ public class MinecraftChunkGeneratorWrapper extends net.minecraft.world.gen.chun
BiomeProvider biomeProvider = pack.getBiomeProvider();
int min = height.getBottomY();
for(int y = height.getTopYInclusive() - 1; y >= min; y--) {
com.dfsek.terra.api.block.state.BlockState terraBlockState = delegate.getBlock(properties, x, y, z, biomeProvider);
BlockState blockState =
(BlockState) (terraBlockState.isExtended() ? ((BlockStateExtended) terraBlockState).getState() : terraBlockState);
if(heightmap
.getBlockPredicate()
.test((BlockState) delegate.getBlock(properties, x, y, z, biomeProvider))) return y + 1;
.test(blockState)) return y + 1;
}
return min;
}
@@ -196,7 +210,10 @@ public class MinecraftChunkGeneratorWrapper extends net.minecraft.world.gen.chun
WorldProperties properties = MinecraftAdapter.adapt(height, SeedHack.getSeed(noiseConfig.getMultiNoiseSampler()));
BiomeProvider biomeProvider = pack.getBiomeProvider();
for(int y = height.getTopYInclusive() - 1; y >= height.getBottomY(); y--) {
array[y - height.getBottomY()] = (BlockState) delegate.getBlock(properties, x, y, z, biomeProvider);
com.dfsek.terra.api.block.state.BlockState terraBlockState = delegate.getBlock(properties, x, y, z, biomeProvider);
BlockState blockState =
(BlockState) (terraBlockState.isExtended() ? ((BlockStateExtended) terraBlockState).getState() : terraBlockState);
array[y - height.getBottomY()] = blockState;
}
return new VerticalBlockSample(height.getBottomY(), array);
}
@@ -17,18 +17,31 @@
package com.dfsek.terra.mod.handle;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.command.argument.BlockArgumentParser;
import net.minecraft.command.argument.BlockArgumentParser.BlockResult;
import net.minecraft.command.argument.BlockStateArgument;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.StringNbtReader;
import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry.Reference;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.state.BlockStateExtended;
import com.dfsek.terra.api.entity.EntityType;
import com.dfsek.terra.api.handle.WorldHandle;
import com.dfsek.terra.mod.implmentation.MinecraftEntityTypeExtended;
import static net.minecraft.command.argument.BlockArgumentParser.INVALID_BLOCK_ID_EXCEPTION;
public class MinecraftWorldHandle implements WorldHandle {
@@ -36,15 +49,35 @@ public class MinecraftWorldHandle implements WorldHandle {
private static final BlockState AIR = (BlockState) Blocks.AIR.getDefaultState();
private static final Logger logger = LoggerFactory.getLogger(MinecraftWorldHandle.class);
@SuppressWarnings("DataFlowIssue")
@Override
public @NotNull BlockState createBlockState(@NotNull String data) {
try {
net.minecraft.block.BlockState state = BlockArgumentParser.block(Registries.BLOCK, data, true)
.blockState();
if(state == null) throw new IllegalArgumentException("Invalid data: " + data);
return (BlockState) state;
BlockResult blockResult = BlockArgumentParser.block(Registries.BLOCK, data, true);
BlockState blockState;
if(blockResult.nbt() != null) {
net.minecraft.block.BlockState state = blockResult.blockState();
NbtCompound nbtCompound = blockResult.nbt();
if(state.hasBlockEntity()) {
BlockEntity blockEntity = ((BlockEntityProvider) state.getBlock()).createBlockEntity(new BlockPos(0, 0, 0), state);
nbtCompound.putInt("x", 0);
nbtCompound.putInt("y", 0);
nbtCompound.putInt("z", 0);
nbtCompound.put("id", BlockEntity.TYPE_CODEC, blockEntity.getType());
blockState = (BlockStateExtended) new BlockStateArgument(state, blockResult.properties().keySet(), nbtCompound);
} else {
blockState = (BlockState) state;
}
} else {
blockState = (BlockState) blockResult.blockState();
}
if(blockState == null) throw new IllegalArgumentException("Invalid data: " + data);
return blockState;
} catch(CommandSyntaxException e) {
throw new IllegalArgumentException(e);
}
@@ -56,10 +89,39 @@ public class MinecraftWorldHandle implements WorldHandle {
}
@Override
public @NotNull EntityType getEntity(@NotNull String id) {
if(!id.contains(":")) throw new IllegalArgumentException("Invalid entity identifier " + id);
Identifier identifier = Identifier.tryParse(id);
if(identifier == null) identifier = Identifier.tryParse(id);
return (EntityType) Registries.ENTITY_TYPE.getEntry(identifier).orElseThrow().value();
public @NotNull EntityType getEntity(@NotNull String data) {
try {
Identifier identifier;
NbtCompound nbtData = null;
StringReader reader = new StringReader(data);
int i = reader.getCursor();
identifier = Identifier.fromCommandInput(reader);
net.minecraft.entity.EntityType<?> entity =
(net.minecraft.entity.EntityType<?>) ((Reference<?>) Registries.ENTITY_TYPE.getOptional(
RegistryKey.of(RegistryKeys.ENTITY_TYPE, identifier)).orElseThrow(() -> {
reader.setCursor(i);
return INVALID_BLOCK_ID_EXCEPTION.createWithContext(reader, identifier.toString());
})).value();
if(reader.canRead() && reader.peek() == '{') {
nbtData = StringNbtReader.readCompoundAsArgument(reader);
nbtData.putString("id", entity.getRegistryEntry().registryKey().getValue().toString());
}
EntityType entityType;
if(nbtData != null) {
entityType = new MinecraftEntityTypeExtended(entity, nbtData);
} else {
entityType = (EntityType) entity;
}
if(identifier == null) throw new IllegalArgumentException("Invalid data: " + data);
return entityType;
} catch(CommandSyntaxException e) {
throw new RuntimeException(e);
}
}
}
@@ -0,0 +1,34 @@
package com.dfsek.terra.mod.implmentation;
import net.minecraft.nbt.NbtCompound;
import com.dfsek.terra.api.data.ExtendedData;
import com.dfsek.terra.api.entity.EntityType;
import com.dfsek.terra.api.entity.EntityTypeExtended;
public record MinecraftEntityTypeExtended(net.minecraft.entity.EntityType<?> entityType, NbtCompound nbtCompound)
implements EntityTypeExtended {
@SuppressWarnings("DataFlowIssue")
@Override
public ExtendedData getData() {
return (ExtendedData) ((Object) nbtCompound);
}
@SuppressWarnings("DataFlowIssue")
@Override
public EntityTypeExtended setData(ExtendedData data) {
return new MinecraftEntityTypeExtended(entityType,
data.getClass().equals(NbtCompound.class) ? ((NbtCompound) ((Object) data)) : null);
}
@Override
public EntityType getType() {
return (EntityType) entityType;
}
@Override
public Object getHandle() {
return entityType;
}
}
@@ -0,0 +1,15 @@
package com.dfsek.terra.mod.mixin.access;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.WorldChunk;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(WorldChunk.class)
public interface WorldChunkAccessor {
@Invoker("loadBlockEntity")
public BlockEntity invokeLoadBlockEntity(BlockPos pos, NbtCompound nbt);
}
@@ -36,6 +36,7 @@ import com.dfsek.terra.api.block.entity.MobSpawner;
import com.dfsek.terra.api.block.entity.SerialState;
import com.dfsek.terra.api.entity.EntityType;
import com.dfsek.terra.mod.CommonPlatform;
import com.dfsek.terra.mod.implmentation.MinecraftEntityTypeExtended;
import com.dfsek.terra.mod.mixin.access.MobSpawnerLogicAccessor;
@@ -66,7 +67,10 @@ public abstract class MobSpawnerBlockEntityMixin extends BlockEntity {
} else {
rand = Random.create();
}
setEntityType((net.minecraft.entity.EntityType<?>) creatureType, rand);
net.minecraft.entity.EntityType<?> entityType =
(((net.minecraft.entity.EntityType<?>) (creatureType.isExtended() && creatureType.getClass().equals(
MinecraftEntityTypeExtended.class) ? ((MinecraftEntityTypeExtended) creatureType).getType() : creatureType)));
setEntityType(entityType, rand);
}
public int terra$getDelay() {
@@ -0,0 +1,94 @@
package com.dfsek.terra.mod.mixin.implementations.terra.block.state;
import net.minecraft.block.BlockState;
import net.minecraft.block.pattern.CachedBlockPosition;
import net.minecraft.command.argument.BlockStateArgument;
import net.minecraft.nbt.NbtCompound;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Intrinsic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.Set;
import java.util.function.Predicate;
import com.dfsek.terra.api.block.BlockType;
import com.dfsek.terra.api.block.state.BlockStateExtended;
import com.dfsek.terra.api.block.state.properties.Property;
import com.dfsek.terra.api.data.ExtendedData;
@Mixin(BlockStateArgument.class)
@Implements(@Interface(iface = BlockStateExtended.class, prefix = "terra$"))
public abstract class BlockStateArgumentMixin implements Predicate<CachedBlockPosition> {
@Shadow
@Nullable
@Final
private NbtCompound data;
@Shadow
public abstract BlockState getBlockState();
@Shadow
public abstract Set<net.minecraft.state.property.Property<?>> getProperties();
public boolean terra$matches(com.dfsek.terra.api.block.state.BlockState other) {
return ((com.dfsek.terra.api.block.state.BlockState) getBlockState()).matches(other);
}
@Intrinsic
public <T extends Comparable<T>> boolean terra$has(com.dfsek.terra.api.block.state.properties.Property<T> property) {
return ((com.dfsek.terra.api.block.state.BlockState) getBlockState()).has(property);
}
@Intrinsic
public <T extends Comparable<T>> T terra$get(com.dfsek.terra.api.block.state.properties.Property<T> property) {
return ((com.dfsek.terra.api.block.state.BlockState) getBlockState()).get(property);
}
@Intrinsic
public <T extends Comparable<T>> com.dfsek.terra.api.block.state.BlockState terra$set(Property<T> property, T value) {
return ((com.dfsek.terra.api.block.state.BlockState) getBlockState()).set(property, value);
}
@Intrinsic
public BlockType terra$getBlockType() {
return ((com.dfsek.terra.api.block.state.BlockState) getBlockState()).getBlockType();
}
@Intrinsic
public String terra$getAsString(boolean properties) {
return ((com.dfsek.terra.api.block.state.BlockState) getBlockState()).getAsString(properties);
}
@Intrinsic
public boolean terra$isAir() {
return ((com.dfsek.terra.api.block.state.BlockState) getBlockState()).isAir();
}
@SuppressWarnings({ "ConstantValue", "DataFlowIssue", "EqualsBetweenInconvertibleTypes" })
@Intrinsic
public BlockStateExtended terra$setData(ExtendedData data) {
return (BlockStateExtended) new BlockStateArgument(getBlockState(), getProperties(),
data.getClass().equals(NbtCompound.class) ? ((NbtCompound) ((Object) data)) : null);
}
@SuppressWarnings("DataFlowIssue")
@Intrinsic
public ExtendedData terra$getData() {
return ((ExtendedData) ((Object) data));
}
@Intrinsic
public com.dfsek.terra.api.block.state.BlockState terra$getState() {
return (com.dfsek.terra.api.block.state.BlockState) getBlockState();
}
public Object terra$getHandle() {
return getBlockState();
}
}
@@ -17,9 +17,19 @@
package com.dfsek.terra.mod.mixin.implementations.terra.chunk;
import com.dfsek.seismic.math.coord.CoordFunctions;
import net.minecraft.block.Block;
import net.minecraft.command.argument.BlockStateArgument;
import net.minecraft.fluid.Fluid;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.ChunkRegion;
import net.minecraft.world.StructureWorldAccess;
import net.minecraft.world.tick.MultiTickScheduler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
@@ -27,20 +37,62 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.state.BlockStateExtended;
import com.dfsek.terra.api.world.chunk.Chunk;
import com.dfsek.terra.mod.util.MinecraftUtil;
@Mixin(ChunkRegion.class)
@Implements(@Interface(iface = Chunk.class, prefix = "terraChunk$"))
public abstract class ChunkRegionMixin {
public abstract class ChunkRegionMixin implements StructureWorldAccess {
@Shadow
@Final
private net.minecraft.world.chunk.Chunk centerPos;
public void terraChunk$setBlock(int x, int y, int z, @NotNull BlockState blockState, boolean physics) {
((ChunkRegion) (Object) this).setBlockState(new BlockPos(x + (centerPos.getPos().x << 4), y, z + (centerPos.getPos().z << 4)),
(net.minecraft.block.BlockState) blockState, 0);
@Shadow
@Final
private ServerWorld world;
@Shadow
@Final
private MultiTickScheduler<Block> blockTickScheduler;
@Shadow
@Final
private MultiTickScheduler<Fluid> fluidTickScheduler;
@Shadow
public abstract net.minecraft.block.BlockState getBlockState(BlockPos pos);
@Shadow
@Nullable
public abstract boolean setBlockState(BlockPos pos, net.minecraft.block.BlockState state, int flags, int maxUpdateDepth);
public void terraChunk$setBlock(int x, int y, int z, @NotNull BlockState data, boolean physics) {
ChunkPos pos = centerPos.getPos();
BlockPos blockPos = new BlockPos(CoordFunctions.chunkAndRelativeToAbsolute(pos.x, x), y,
CoordFunctions.chunkAndRelativeToAbsolute(pos.z, z));
net.minecraft.block.BlockState state;
boolean isExtended = MinecraftUtil.isCompatibleBlockStateExtended(data);
if(isExtended) {
BlockStateArgument arg = ((BlockStateArgument) data);
state = arg.getBlockState();
setBlockState(blockPos, state, 0, 512);
net.minecraft.world.chunk.Chunk chunk = getChunk(blockPos);
NbtCompound nbt = ((NbtCompound) (Object) ((BlockStateExtended) data).getData());
MinecraftUtil.loadBlockEntity(chunk, world, blockPos, state, nbt);
} else {
state = (net.minecraft.block.BlockState) data;
setBlockState(blockPos, state, 0, 512);
}
if(physics) {
MinecraftUtil.schedulePhysics(state, blockPos, getFluidTickScheduler(), getBlockTickScheduler());
}
}
public @NotNull BlockState terraChunk$getBlock(int x, int y, int z) {
@@ -17,9 +17,11 @@
package com.dfsek.terra.mod.mixin.implementations.terra.chunk;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.command.argument.BlockStateArgument;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.WorldChunk;
import net.minecraft.world.tick.OrderedTick;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
@@ -30,8 +32,10 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.state.BlockStateExtended;
import com.dfsek.terra.api.world.ServerWorld;
import com.dfsek.terra.api.world.chunk.Chunk;
import com.dfsek.terra.mod.util.MinecraftUtil;
@Mixin(WorldChunk.class)
@@ -48,23 +52,34 @@ public abstract class WorldChunkMixin {
@Nullable
public abstract net.minecraft.block.BlockState setBlockState(BlockPos pos, net.minecraft.block.BlockState state, int flags);
@Shadow
protected abstract BlockEntity loadBlockEntity(BlockPos pos, NbtCompound nbt);
@SuppressWarnings("ConstantValue")
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, 0);
if(physics) {
net.minecraft.block.BlockState state = ((net.minecraft.block.BlockState) data);
if(state.isLiquid()) {
world.getFluidTickScheduler().scheduleTick(OrderedTick.create(state.getFluidState().getFluid(), blockPos));
} else {
world.getBlockTickScheduler().scheduleTick(OrderedTick.create(state.getBlock(), blockPos));
}
net.minecraft.block.BlockState state;
boolean isExtended = MinecraftUtil.isCompatibleBlockStateExtended(data);
if(isExtended) {
BlockStateArgument arg = ((BlockStateArgument) data);
state = arg.getBlockState();
setBlockState(blockPos, state, 0);
loadBlockEntity(blockPos, ((NbtCompound) (Object) ((BlockStateExtended) data).getData()));
} else {
state = (net.minecraft.block.BlockState) data;
setBlockState(blockPos, state, 0);
}
if(physics) {
MinecraftUtil.schedulePhysics(state, blockPos, world.getFluidTickScheduler(), world.getBlockTickScheduler());
}
}
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,
0);
@SuppressWarnings("ConstantValue")
public void terra$setBlock(int x, int y, int z, @NotNull BlockState data) {
terra$setBlock(x, y, z, data, false);
}
@Intrinsic
@@ -17,30 +17,52 @@
package com.dfsek.terra.mod.mixin.implementations.terra.chunk.data;
import net.minecraft.command.argument.BlockStateArgument;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.HeightLimitView;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkSection;
import net.minecraft.world.chunk.PalettesFactory;
import net.minecraft.world.chunk.UpgradeData;
import net.minecraft.world.gen.chunk.BlendingData;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.state.BlockStateExtended;
import com.dfsek.terra.api.world.chunk.generation.ProtoChunk;
@Mixin(net.minecraft.world.chunk.ProtoChunk.class)
@Implements(@Interface(iface = ProtoChunk.class, prefix = "terra$"))
public abstract class ProtoChunkMixin {
public abstract class ProtoChunkMixin extends Chunk {
public ProtoChunkMixin(ChunkPos pos, UpgradeData upgradeData, HeightLimitView heightLimitView, PalettesFactory palettesFactory,
long inhabitedTime, @Nullable ChunkSection[] sectionArray, @Nullable BlendingData blendingData) {
super(pos, upgradeData, heightLimitView, palettesFactory, inhabitedTime, sectionArray, blendingData);
}
@Shadow
public abstract net.minecraft.block.BlockState getBlockState(BlockPos pos);
@Shadow
public abstract HeightLimitView getHeightLimitView();
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,
0);
public void terra$setBlock(int x, int y, int z, @NotNull BlockState data) {
BlockPos blockPos = new BlockPos(x, y, z);
boolean isExtended = data.isExtended() && data.getClass().equals(BlockStateArgument.class);
if(isExtended) {
BlockStateExtended blockStateExtended = (BlockStateExtended) data;
net.minecraft.block.BlockState blockState = (net.minecraft.block.BlockState) blockStateExtended.getState();
this.setBlockState(blockPos, blockState, 0);
} else {
this.setBlockState(blockPos, (net.minecraft.block.BlockState) data, 0);
}
}
public @NotNull BlockState terra$getBlock(int x, int y, int z) {
@@ -0,0 +1,20 @@
package com.dfsek.terra.mod.mixin.implementations.terra.nbt;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Intrinsic;
import org.spongepowered.asm.mixin.Mixin;
import com.dfsek.terra.api.data.ExtendedData;
@Mixin(NbtCompound.class)
@Implements(@Interface(iface = ExtendedData.class, prefix = "terra$"))
public abstract class NbtCompoundMixin implements NbtElement {
@Intrinsic
public String terra$toString() {
return this.toString();
}
}
@@ -17,17 +17,18 @@
package com.dfsek.terra.mod.mixin.implementations.terra.world;
import net.minecraft.block.FluidBlock;
import net.minecraft.block.Block;
import net.minecraft.command.argument.BlockStateArgument;
import net.minecraft.entity.SpawnReason;
import net.minecraft.fluid.Fluid;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.collection.BoundedRegionArray;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ChunkRegion;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.StructureWorldAccess;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkGenerationStep;
import net.minecraft.world.tick.MultiTickScheduler;
import net.minecraft.world.tick.OrderedTick;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
@@ -40,6 +41,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.dfsek.terra.api.block.entity.BlockEntity;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.state.BlockStateExtended;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.entity.Entity;
import com.dfsek.terra.api.entity.EntityType;
@@ -48,13 +50,13 @@ 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.ProtoWorld;
import com.dfsek.terra.mod.generation.MinecraftChunkGeneratorWrapper;
import com.dfsek.terra.mod.mixin.invoke.FluidBlockInvoker;
import com.dfsek.terra.mod.implmentation.MinecraftEntityTypeExtended;
import com.dfsek.terra.mod.util.MinecraftUtil;
@Mixin(ChunkRegion.class)
@Implements(@Interface(iface = ProtoWorld.class, prefix = "terraWorld$"))
public abstract class ChunkRegionMixin {
public abstract class ChunkRegionMixin implements StructureWorldAccess {
private ConfigPack terra$config;
@@ -73,6 +75,10 @@ public abstract class ChunkRegionMixin {
@Final
private MultiTickScheduler<Fluid> fluidTickScheduler;
@Shadow
@Final
private MultiTickScheduler<Block> blockTickScheduler;
@Inject(at = @At("RETURN"),
method = "<init>(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/util/collection/BoundedRegionArray;" +
@@ -85,12 +91,26 @@ public abstract class ChunkRegionMixin {
@Intrinsic(displace = true)
public void terraWorld$setBlockState(int x, int y, int z, BlockState data, boolean physics) {
BlockPos pos = new BlockPos(x, y, z);
((ChunkRegion) (Object) this).setBlockState(pos, (net.minecraft.block.BlockState) data, physics ? 3 : 1042);
if(physics && ((net.minecraft.block.BlockState) data).getBlock() instanceof FluidBlock) {
fluidTickScheduler.scheduleTick(
OrderedTick.create((((FluidBlockInvoker) ((net.minecraft.block.BlockState) data).getBlock())).invokeGetFluidState(
(net.minecraft.block.BlockState) data).getFluid(), pos));
BlockPos blockPos = new BlockPos(x, y, z);
net.minecraft.block.BlockState state;
int flags = physics ? 3 : 1042;
boolean isExtended = MinecraftUtil.isCompatibleBlockStateExtended(data);
if(isExtended) {
BlockStateArgument arg = ((BlockStateArgument) data);
state = arg.getBlockState();
setBlockState(blockPos, state, flags);
net.minecraft.world.chunk.Chunk chunk = getChunk(blockPos);
NbtCompound nbt = ((NbtCompound) (Object) ((BlockStateExtended) data).getData());
MinecraftUtil.loadBlockEntity(chunk, world, blockPos, state, nbt);
} else {
state = (net.minecraft.block.BlockState) data;
setBlockState(blockPos, state, flags);
}
if(physics) {
MinecraftUtil.schedulePhysics(state, blockPos, getFluidTickScheduler(), getBlockTickScheduler());
}
}
@@ -106,11 +126,11 @@ public abstract class ChunkRegionMixin {
@Intrinsic(displace = true)
public BlockState terraWorld$getBlockState(int x, int y, int z) {
BlockPos pos = new BlockPos(x, y, z);
return (BlockState) ((ChunkRegion) (Object) this).getBlockState(pos);
return (BlockState) (this).getBlockState(pos);
}
public BlockEntity terraWorld$getBlockEntity(int x, int y, int z) {
return MinecraftUtil.createState((WorldAccess) this, new BlockPos(x, y, z));
return MinecraftUtil.createBlockEntity(this, new BlockPos(x, y, z));
}
public int terraWorld$getMinHeight() {
@@ -125,10 +145,24 @@ public abstract class ChunkRegionMixin {
return terra$config.getBiomeProvider();
}
public Entity terraWorld$spawnEntity(double x, double y, double z, EntityType entityType) {
net.minecraft.entity.Entity entity = ((net.minecraft.entity.EntityType<?>) entityType).create(world, SpawnReason.CHUNK_GENERATION);
entity.setPos(x, y, z);
((ChunkRegion) (Object) this).spawnEntity(entity);
@SuppressWarnings("DataFlowIssue")
public Entity terraWorld$spawnEntity(double x, double y, double z, EntityType data) {
boolean isExtended = MinecraftUtil.isCompatibleEntityTypeExtended(data);
net.minecraft.entity.Entity entity;
if(isExtended) {
MinecraftEntityTypeExtended type = ((MinecraftEntityTypeExtended) data);
NbtCompound nbt = (NbtCompound) ((Object) type.getData());
entity = net.minecraft.entity.EntityType.loadEntityWithPassengers(nbt, world, SpawnReason.CHUNK_GENERATION, (entityx) -> {
entityx.refreshPositionAndAngles(x, y, z, entityx.getYaw(), entityx.getPitch());
return entityx;
});
spawnEntity(entity);
} else {
entity = ((net.minecraft.entity.EntityType<?>) data).create(world, SpawnReason.CHUNK_GENERATION);
entity.setPos(x, y, z);
spawnEntity(entity);
}
return (Entity) entity;
}
@@ -17,16 +17,28 @@
package com.dfsek.terra.mod.mixin.implementations.terra.world;
import net.minecraft.block.Block;
import net.minecraft.command.argument.BlockStateArgument;
import net.minecraft.entity.SpawnReason;
import net.minecraft.fluid.Fluid;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.MutableWorldProperties;
import net.minecraft.world.World;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.tick.WorldTickScheduler;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Intrinsic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.dfsek.terra.api.block.entity.BlockEntity;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.state.BlockStateExtended;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.entity.Entity;
import com.dfsek.terra.api.entity.EntityType;
@@ -36,49 +48,95 @@ import com.dfsek.terra.api.world.chunk.Chunk;
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
import com.dfsek.terra.mod.generation.MinecraftChunkGeneratorWrapper;
import com.dfsek.terra.mod.generation.TerraBiomeSource;
import com.dfsek.terra.mod.implmentation.MinecraftEntityTypeExtended;
import com.dfsek.terra.mod.mixin.access.WorldChunkAccessor;
import com.dfsek.terra.mod.util.MinecraftUtil;
@Mixin(net.minecraft.server.world.ServerWorld.class)
@Implements(@Interface(iface = ServerWorld.class, prefix = "terra$"))
public abstract class ServerWorldMixin {
public Entity terra$spawnEntity(double x, double y, double z, EntityType entityType) {
net.minecraft.entity.Entity entity = ((net.minecraft.entity.EntityType<?>) entityType).create(null, SpawnReason.CHUNK_GENERATION);
entity.setPos(x, y, z);
((net.minecraft.server.world.ServerWorld) (Object) this).spawnEntity(entity);
public abstract class ServerWorldMixin extends World {
protected ServerWorldMixin(MutableWorldProperties properties, RegistryKey<World> registryRef, DynamicRegistryManager registryManager,
RegistryEntry<DimensionType> dimensionEntry, boolean isClient, boolean debugWorld, long seed,
int maxChainedNeighborUpdates) {
super(properties, registryRef, registryManager, dimensionEntry, isClient, debugWorld, seed, maxChainedNeighborUpdates);
}
@Shadow
public abstract WorldTickScheduler<Block> getBlockTickScheduler();
@Shadow
public abstract WorldTickScheduler<Fluid> getFluidTickScheduler();
public Entity terra$spawnEntity(double x, double y, double z, EntityType data) {
boolean isExtended = MinecraftUtil.isCompatibleEntityTypeExtended(data);
net.minecraft.entity.Entity entity;
if(isExtended) {
MinecraftEntityTypeExtended type = ((MinecraftEntityTypeExtended) data);
NbtCompound nbt = (NbtCompound) ((Object) type.getData());
entity = net.minecraft.entity.EntityType.loadEntityWithPassengers(nbt, this, SpawnReason.CHUNK_GENERATION, (entityx) -> {
entityx.refreshPositionAndAngles(x, y, z, entityx.getYaw(), entityx.getPitch());
return entityx;
});
spawnEntity(entity);
} else {
entity = ((net.minecraft.entity.EntityType<?>) data).create(this, SpawnReason.CHUNK_GENERATION);
entity.setPos(x, y, z);
spawnEntity(entity);
}
return (Entity) entity;
}
public void terra$setBlockState(int x, int y, int z, BlockState data, boolean physics) {
BlockPos pos = new BlockPos(x, y, z);
((net.minecraft.server.world.ServerWorld) (Object) this).setBlockState(pos, (net.minecraft.block.BlockState) data,
physics ? 3 : 1042);
BlockPos blockPos = new BlockPos(x, y, z);
net.minecraft.block.BlockState state;
int flags = physics ? 3 : 1042;
boolean isExtended = MinecraftUtil.isCompatibleBlockStateExtended(data);
if(isExtended) {
BlockStateArgument arg = ((BlockStateArgument) data);
state = arg.getBlockState();
setBlockState(blockPos, state, flags);
net.minecraft.world.chunk.Chunk chunk = getWorldChunk(blockPos);
((WorldChunkAccessor) chunk).invokeLoadBlockEntity(blockPos, ((NbtCompound) (Object) ((BlockStateExtended) data).getData()));
} else {
state = (net.minecraft.block.BlockState) data;
setBlockState(blockPos, state, flags);
}
if(physics) {
MinecraftUtil.schedulePhysics(state, blockPos, this.getFluidTickScheduler(), this.getBlockTickScheduler());
}
}
@Intrinsic
public long terra$getSeed() {
return ((net.minecraft.server.world.ServerWorld) (Object) this).getSeed();
}
public int terra$getMaxHeight() {
return (((net.minecraft.server.world.ServerWorld) (Object) this).getBottomY()) +
((net.minecraft.server.world.ServerWorld) (Object) this).getHeight();
return ((this).getBottomY()) +
(this).getHeight();
}
public Chunk terra$getChunkAt(int x, int z) {
return (Chunk) ((net.minecraft.server.world.ServerWorld) (Object) this).getChunk(x, z);
return (Chunk) (this).getChunk(x, z);
}
public BlockState terra$getBlockState(int x, int y, int z) {
return (BlockState) ((net.minecraft.server.world.ServerWorld) (Object) this).getBlockState(new BlockPos(x, y, z));
return (BlockState) (this).getBlockState(new BlockPos(x, y, z));
}
public BlockEntity terra$getBlockEntity(int x, int y, int z) {
return MinecraftUtil.createState((WorldAccess) this, new BlockPos(x, y, z));
return MinecraftUtil.createBlockEntity(this, new BlockPos(x, y, z));
}
public int terra$getMinHeight() {
return ((net.minecraft.server.world.ServerWorld) (Object) this).getBottomY();
return (this).getBottomY();
}
public ChunkGenerator terra$getGenerator() {
@@ -1,8 +1,14 @@
package com.dfsek.terra.mod.util;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.LootableContainerBlockEntity;
import net.minecraft.block.entity.MobSpawnerBlockEntity;
import net.minecraft.block.entity.SignBlockEntity;
import net.minecraft.command.argument.BlockStateArgument;
import net.minecraft.fluid.Fluid;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
@@ -10,10 +16,14 @@ import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.intprovider.IntProviderType;
import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.tick.OrderedTick;
import net.minecraft.world.tick.TickScheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -25,11 +35,13 @@ import com.dfsek.terra.api.block.entity.Container;
import com.dfsek.terra.api.block.entity.MobSpawner;
import com.dfsek.terra.api.block.entity.Sign;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.entity.EntityType;
import com.dfsek.terra.api.util.range.ConstantRange;
import com.dfsek.terra.mod.CommonPlatform;
import com.dfsek.terra.mod.config.PreLoadCompatibilityOptions;
import com.dfsek.terra.mod.config.ProtoPlatformBiome;
import com.dfsek.terra.mod.data.Codecs;
import com.dfsek.terra.mod.implmentation.MinecraftEntityTypeExtended;
import com.dfsek.terra.mod.implmentation.TerraIntProvider;
import com.dfsek.terra.mod.mixin_ifaces.FloraFeatureHolder;
@@ -46,7 +58,7 @@ public final class MinecraftUtil {
.flatMap(id -> Optional.ofNullable(registry.getEntry(id)));
}
public static BlockEntity createState(WorldAccess worldAccess, BlockPos pos) {
public static BlockEntity createBlockEntity(WorldAccess worldAccess, BlockPos pos) {
net.minecraft.block.entity.BlockEntity entity = worldAccess.getBlockEntity(pos);
if(entity instanceof SignBlockEntity) {
return (Sign) entity;
@@ -58,6 +70,42 @@ public final class MinecraftUtil {
return null;
}
public static void schedulePhysics(BlockState blockState, BlockPos blockPos, TickScheduler<Fluid> fluidScheduler,
TickScheduler<Block> blockScheduler) {
if(blockState.isLiquid()) {
fluidScheduler.scheduleTick(OrderedTick.create(blockState.getFluidState().getFluid(), blockPos));
} else {
blockScheduler.scheduleTick(OrderedTick.create(blockState.getBlock(), blockPos));
}
}
public static boolean isCompatibleBlockStateExtended(com.dfsek.terra.api.block.state.BlockState blockState) {
return blockState.isExtended() && BlockStateArgument.class.isAssignableFrom(blockState.getClass());
}
//[Vanilla Copy]
public static void loadBlockEntity(Chunk chunk, World world, BlockPos blockPos, BlockState state, NbtCompound nbt) {
net.minecraft.block.entity.BlockEntity blockEntity;
if("DUMMY".equals(nbt.getString("id", ""))) {
if(state.hasBlockEntity()) {
blockEntity = ((BlockEntityProvider) state.getBlock()).createBlockEntity(blockPos, state);
} else {
blockEntity = null;
}
} else {
blockEntity = net.minecraft.block.entity.BlockEntity.createFromNbt(blockPos, state, nbt, world.getRegistryManager());
}
if(blockEntity != null) {
blockEntity.setWorld(world);
chunk.setBlockEntity(blockEntity);
}
}
public static boolean isCompatibleEntityTypeExtended(EntityType entityType) {
return entityType.isExtended() && MinecraftEntityTypeExtended.class.isAssignableFrom(entityType.getClass());
}
public static void registerIntProviderTypes() {
IntProviderType<TerraIntProvider> CONSTANT = IntProviderType.register("terra:constant_range",
Codecs.TERRA_CONSTANT_RANGE_INT_PROVIDER_TYPE);
@@ -40,7 +40,8 @@ public class PresetUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(PresetUtil.class);
private static final List<Pair<Identifier, Boolean>> PRESETS = new ArrayList<>();
public static Pair<Identifier, WorldPreset> createDefault(ConfigPack pack, ModPlatform platform, boolean extended) {
public static Pair<Identifier, WorldPreset> createDefault(ConfigPack pack, ModPlatform platform, boolean extended,
boolean packInMetapack) {
Registry<DimensionType> dimensionTypeRegistry = platform.dimensionTypeRegistry();
Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry = platform.chunkGeneratorSettingsRegistry();
Registry<MultiNoiseBiomeSourceParameterList> multiNoiseBiomeSourceParameterLists =
@@ -55,7 +56,8 @@ public class PresetUtil {
HashMap<RegistryKey<DimensionOptions>, DimensionOptions> dimensionMap = new HashMap<>();
insertCustom(platform, "minecraft:overworld", pack, dimensionTypeRegistry, chunkGeneratorSettingsRegistry, dimensionMap);
insertCustom(platform, "minecraft:overworld", pack, dimensionTypeRegistry, chunkGeneratorSettingsRegistry, dimensionMap,
packInMetapack);
insertDefaults(dimensionTypeRegistry, chunkGeneratorSettingsRegistry, multiNoiseBiomeSourceParameterLists, platform.biomeRegistry(),
dimensionMap);
@@ -80,7 +82,7 @@ public class PresetUtil {
HashMap<RegistryKey<DimensionOptions>, DimensionOptions> dimensionMap = new HashMap<>();
metaPack.packs().forEach((key, pack) -> {
insertCustom(platform, key, pack, dimensionTypeRegistry, chunkGeneratorSettingsRegistry, dimensionMap);
insertCustom(platform, key, pack, dimensionTypeRegistry, chunkGeneratorSettingsRegistry, dimensionMap, false);
});
insertDefaults(dimensionTypeRegistry, chunkGeneratorSettingsRegistry, multiNoiseBiomeSourceParameterLists, platform.biomeRegistry(),
@@ -93,7 +95,7 @@ public class PresetUtil {
private static void insertCustom(ModPlatform platform, String key, ConfigPack pack, Registry<DimensionType> dimensionTypeRegistry,
Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry,
HashMap<RegistryKey<DimensionOptions>, DimensionOptions> dimensionMap) {
HashMap<RegistryKey<DimensionOptions>, DimensionOptions> dimensionMap, boolean packInMetapack) {
Identifier demensionIdentifier = Identifier.of(key);
VanillaWorldProperties vanillaWorldProperties;
@@ -108,12 +110,18 @@ public class PresetUtil {
assert defaultDimension != null;
DimensionType dimensionType = DimensionUtil.createDimension(vanillaWorldProperties, defaultDimension, platform);
RegistryKey<DimensionType> dimensionTypeRegistryKey = MinecraftUtil.registerDimensionTypeKey(
Identifier.of("terra", pack.getID().toLowerCase(
Locale.ROOT)));
Identifier dimensionTypeID = Identifier.of("terra", pack.getID().toLowerCase(Locale.ROOT));
Registry.registerReference(dimensionTypeRegistry, dimensionTypeRegistryKey, dimensionType);
DimensionType dimensionType;
if(!packInMetapack) {
dimensionType = DimensionUtil.createDimension(vanillaWorldProperties, defaultDimension, platform);
RegistryKey<DimensionType> dimensionTypeRegistryKey = MinecraftUtil.registerDimensionTypeKey(
dimensionTypeID);
Registry.registerReference(dimensionTypeRegistry, dimensionTypeRegistryKey, dimensionType);
} else {
dimensionType = dimensionTypeRegistry.get(dimensionTypeID);
}
RegistryEntry<DimensionType> dimensionTypeRegistryEntry = dimensionTypeRegistry.getEntry(dimensionType);
@@ -2,4 +2,6 @@ accessWidener v1 named
accessible class net/minecraft/world/biome/Biome$Weather
accessible class net/minecraft/world/gen/WorldPresets$Registrar
accessible field net/minecraft/world/dimension/DimensionOptionsRegistryHolder VANILLA_KEYS Ljava/util/Set;
accessible class net/minecraft/registry/RegistryLoader$Loader
accessible class net/minecraft/registry/RegistryLoader$Loader
extendable class net/minecraft/nbt/NbtElement
accessible field net/minecraft/block/entity/BlockEntity TYPE_CODEC Lcom/mojang/serialization/Codec;
@@ -9,6 +9,7 @@
"access.StateAccessor",
"access.StructureAccessorAccessor",
"access.VillagerTypeAccessor",
"access.WorldChunkAccessor",
"generalize.ServerWorldMixin",
"implementations.compat.GenerationSettingsFloraFeaturesMixin",
"implementations.terra.BiomeMixin",
@@ -18,6 +19,7 @@
"implementations.terra.block.entity.LootableContainerBlockEntityMixin",
"implementations.terra.block.entity.MobSpawnerBlockEntityMixin",
"implementations.terra.block.entity.SignBlockEntityMixin",
"implementations.terra.block.state.BlockStateArgumentMixin",
"implementations.terra.block.state.BlockStateMixin",
"implementations.terra.block.state.PropertyMixin",
"implementations.terra.chunk.ChunkRegionMixin",
@@ -33,6 +35,7 @@
"implementations.terra.inventory.meta.EnchantmentMixin",
"implementations.terra.inventory.meta.ItemStackDamageableMixin",
"implementations.terra.inventory.meta.ItemStackMetaMixin",
"implementations.terra.nbt.NbtCompoundMixin",
"implementations.terra.world.ChunkRegionMixin",
"implementations.terra.world.ServerWorldMixin",
"invoke.BiomeInvoker",