mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-08-16 00:15:41 +00:00
Merge remote-tracking branch 'everbuild-org/feat/platform/minestom' into ver/6.6.0
This commit is contained in:
commit
a61c6b8a97
@ -44,6 +44,7 @@ afterEvaluate {
|
|||||||
configureDistribution()
|
configureDistribution()
|
||||||
}
|
}
|
||||||
project(":platforms:bukkit:common").configureDistribution()
|
project(":platforms:bukkit:common").configureDistribution()
|
||||||
|
project(":platforms:minestom:example").configureDistribution()
|
||||||
forSubProjects(":common:addons") {
|
forSubProjects(":common:addons") {
|
||||||
apply(plugin = "com.gradleup.shadow")
|
apply(plugin = "com.gradleup.shadow")
|
||||||
|
|
||||||
|
@ -4,9 +4,11 @@ import java.io.File
|
|||||||
import java.io.FileWriter
|
import java.io.FileWriter
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.file.FileSystems
|
import java.nio.file.FileSystems
|
||||||
|
import java.nio.file.Path
|
||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.plugins.BasePluginExtension
|
import org.gradle.api.plugins.BasePluginExtension
|
||||||
|
import org.gradle.jvm.tasks.Jar
|
||||||
import org.gradle.kotlin.dsl.apply
|
import org.gradle.kotlin.dsl.apply
|
||||||
import org.gradle.kotlin.dsl.configure
|
import org.gradle.kotlin.dsl.configure
|
||||||
import org.gradle.kotlin.dsl.extra
|
import org.gradle.kotlin.dsl.extra
|
||||||
@ -19,6 +21,25 @@ import kotlin.io.path.createDirectories
|
|||||||
import kotlin.io.path.createFile
|
import kotlin.io.path.createFile
|
||||||
import kotlin.io.path.exists
|
import kotlin.io.path.exists
|
||||||
|
|
||||||
|
private fun Project.installAddonsInto(dest: Path) {
|
||||||
|
FileSystems.newFileSystem(dest, mapOf("create" to "false"), null).use { fs ->
|
||||||
|
forSubProjects(":common:addons") {
|
||||||
|
val jar = getJarTask()
|
||||||
|
|
||||||
|
logger.info("Packaging addon ${jar.archiveFileName.get()} to $dest. size: ${jar.archiveFile.get().asFile.length() / 1024}KB")
|
||||||
|
|
||||||
|
val boot = if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "bootstrap/" else ""
|
||||||
|
val addonPath = fs.getPath("/addons/$boot${jar.archiveFileName.get()}")
|
||||||
|
|
||||||
|
if (!addonPath.exists()) {
|
||||||
|
addonPath.parent.createDirectories()
|
||||||
|
addonPath.createFile()
|
||||||
|
jar.archiveFile.get().asFile.toPath().copyTo(addonPath, overwrite = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun Project.configureDistribution() {
|
fun Project.configureDistribution() {
|
||||||
apply(plugin = "com.gradleup.shadow")
|
apply(plugin = "com.gradleup.shadow")
|
||||||
@ -48,25 +69,17 @@ fun Project.configureDistribution() {
|
|||||||
doLast {
|
doLast {
|
||||||
// https://github.com/johnrengelman/shadow/issues/111
|
// https://github.com/johnrengelman/shadow/issues/111
|
||||||
val dest = tasks.named<ShadowJar>("shadowJar").get().archiveFile.get().path
|
val dest = tasks.named<ShadowJar>("shadowJar").get().archiveFile.get().path
|
||||||
|
installAddonsInto(dest)
|
||||||
|
}
|
||||||
FileSystems.newFileSystem(dest, mapOf("create" to "false"), null).use { fs ->
|
}
|
||||||
forSubProjects(":common:addons") {
|
|
||||||
val jar = getJarTask()
|
tasks.create("installAddonsIntoDefaultJar") {
|
||||||
|
group = "terra"
|
||||||
logger.info("Packaging addon ${jar.archiveFileName.get()} to $dest. size: ${jar.archiveFile.get().asFile.length() / 1024}KB")
|
dependsOn(compileAddons)
|
||||||
|
|
||||||
val boot = if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "bootstrap/" else ""
|
doLast {
|
||||||
val addonPath = fs.getPath("/addons/$boot${jar.archiveFileName.get()}")
|
val dest = tasks.named<Jar>("jar").get().archiveFile.get().path
|
||||||
|
installAddonsInto(dest)
|
||||||
if (!addonPath.exists()) {
|
|
||||||
addonPath.parent.createDirectories()
|
|
||||||
addonPath.createFile()
|
|
||||||
jar.archiveFile.get().asFile.toPath().copyTo(addonPath, overwrite = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,4 +81,8 @@ object Versions {
|
|||||||
object Allay {
|
object Allay {
|
||||||
const val api = "0.1.3"
|
const val api = "0.1.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Minestom {
|
||||||
|
const val minestom = "187931e50b"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
11
platforms/minestom/build.gradle.kts
Normal file
11
platforms/minestom/build.gradle.kts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
dependencies {
|
||||||
|
shadedApi(project(":common:implementation:base"))
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.named("jar") {
|
||||||
|
finalizedBy("installAddonsIntoDefaultJar")
|
||||||
|
}
|
28
platforms/minestom/example/build.gradle.kts
Normal file
28
platforms/minestom/example/build.gradle.kts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
plugins {
|
||||||
|
application
|
||||||
|
}
|
||||||
|
|
||||||
|
val javaMainClass = "com.dfsek.terra.minestom.TerraMinestomExample"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
shadedApi(project(":platforms:minestom"))
|
||||||
|
|
||||||
|
implementation("net.minestom", "minestom-snapshots", Versions.Minestom.minestom)
|
||||||
|
implementation("org.slf4j", "slf4j-simple", Versions.Libraries.slf4j)
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<Jar> {
|
||||||
|
entryCompression = ZipEntryCompression.STORED
|
||||||
|
manifest {
|
||||||
|
attributes(
|
||||||
|
"Main-Class" to javaMainClass,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainClass.set(javaMainClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.getByName("run").setProperty("workingDir", file("./run"))
|
||||||
|
addonDir(project.file("./run/terra/addons"), tasks.named("run").get())
|
@ -0,0 +1,132 @@
|
|||||||
|
package com.dfsek.terra.minestom;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.command.builder.Command;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
|
import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerSpawnEvent;
|
||||||
|
import net.minestom.server.instance.Instance;
|
||||||
|
import net.minestom.server.instance.LightingChunk;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import com.dfsek.terra.minestom.world.TerraMinestomWorld;
|
||||||
|
import com.dfsek.terra.minestom.world.TerraMinestomWorldBuilder;
|
||||||
|
|
||||||
|
|
||||||
|
public class TerraMinestomExample {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(TerraMinestomExample.class);
|
||||||
|
private final MinecraftServer server = MinecraftServer.init();
|
||||||
|
private Instance instance;
|
||||||
|
private TerraMinestomWorld world;
|
||||||
|
|
||||||
|
public void createNewInstance() {
|
||||||
|
instance = MinecraftServer.getInstanceManager().createInstanceContainer();
|
||||||
|
instance.setChunkSupplier(LightingChunk::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void attachTerra() {
|
||||||
|
world = TerraMinestomWorldBuilder.from(instance)
|
||||||
|
.defaultPack()
|
||||||
|
.attach();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendProgressBar(int current, int max) {
|
||||||
|
String left = "#".repeat((int) ((((float) current) / max) * 20));
|
||||||
|
String right = ".".repeat(20 - left.length());
|
||||||
|
int percent = (int) (((float) current) / max * 100);
|
||||||
|
String percentString = percent + "%";
|
||||||
|
percentString = " ".repeat(4 - percentString.length()) + percentString;
|
||||||
|
String message = percentString + " |" + left + right + "| " + current + "/" + max;
|
||||||
|
logger.info(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void preloadWorldAndMeasure() {
|
||||||
|
int radius = 12;
|
||||||
|
int chunksLoading = (radius * 2 + 1) * (radius * 2 + 1);
|
||||||
|
AtomicInteger chunksLeft = new AtomicInteger(chunksLoading);
|
||||||
|
|
||||||
|
long start = System.nanoTime();
|
||||||
|
for(int x = -radius; x <= radius; x++) {
|
||||||
|
for(int z = -radius; z <= radius; z++) {
|
||||||
|
instance.loadChunk(x, z).thenAccept(chunk -> {
|
||||||
|
int left = chunksLeft.decrementAndGet();
|
||||||
|
if(left == 0) {
|
||||||
|
long end = System.nanoTime();
|
||||||
|
sendProgressBar(chunksLoading - left, chunksLoading);
|
||||||
|
double chunksPerSecond = chunksLoading / ((end - start) / 1000000000.0);
|
||||||
|
logger.info(
|
||||||
|
"Preloaded {} chunks in world in {}ms. That's {} Chunks/s",
|
||||||
|
chunksLoading,
|
||||||
|
(end - start) / 1000000.0,
|
||||||
|
chunksPerSecond
|
||||||
|
);
|
||||||
|
|
||||||
|
world.displayStats();
|
||||||
|
} else if(left % 60 == 0) {
|
||||||
|
sendProgressBar(chunksLoading - left, chunksLoading);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addListeners() {
|
||||||
|
MinecraftServer.getGlobalEventHandler().addListener(AsyncPlayerConfigurationEvent.class, event -> {
|
||||||
|
event.setSpawningInstance(instance);
|
||||||
|
event.getPlayer().setRespawnPoint(new Pos(0.0, 100.0, 0.0));
|
||||||
|
});
|
||||||
|
|
||||||
|
MinecraftServer.getGlobalEventHandler().addListener(PlayerSpawnEvent.class, event -> {
|
||||||
|
event.getPlayer().setGameMode(GameMode.SPECTATOR);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addScheduler() {
|
||||||
|
MinecraftServer.getSchedulerManager().buildTask(() -> world.displayStats())
|
||||||
|
.repeat(Duration.ofSeconds(10))
|
||||||
|
.schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addCommands() {
|
||||||
|
MinecraftServer.getCommandManager().register(new RegenerateCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bind() {
|
||||||
|
logger.info("Starting server on port 25565");
|
||||||
|
server.start("localhost", 25565);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
TerraMinestomExample example = new TerraMinestomExample();
|
||||||
|
example.createNewInstance();
|
||||||
|
example.attachTerra();
|
||||||
|
example.preloadWorldAndMeasure();
|
||||||
|
example.addScheduler();
|
||||||
|
example.addListeners();
|
||||||
|
example.addCommands();
|
||||||
|
example.bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RegenerateCommand extends Command {
|
||||||
|
public RegenerateCommand() {
|
||||||
|
super("regenerate");
|
||||||
|
setDefaultExecutor((sender, context) -> regenerate());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void regenerate() {
|
||||||
|
instance.sendMessage(Component.text("Regenerating world"));
|
||||||
|
createNewInstance();
|
||||||
|
attachTerra();
|
||||||
|
preloadWorldAndMeasure();
|
||||||
|
MinecraftServer.getConnectionManager().getOnlinePlayers().forEach(player ->
|
||||||
|
player.setInstance(instance, new Pos(0, 100, 0))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.dfsek.terra.minestom;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.vector.Vector3;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomAdapter {
|
||||||
|
public static Vector3 adapt(Point point) {
|
||||||
|
return Vector3.of(point.x(), point.y(), point.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Pos adapt(Vector3 vector) {
|
||||||
|
return new Pos(vector.getX(), vector.getY(), vector.getZ());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
package com.dfsek.terra.minestom;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.TypeRegistry;
|
||||||
|
import com.dfsek.tectonic.api.loader.type.TypeLoader;
|
||||||
|
import com.dfsek.terra.AbstractPlatform;
|
||||||
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
|
import com.dfsek.terra.api.entity.EntityType;
|
||||||
|
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
|
||||||
|
import com.dfsek.terra.api.handle.ItemHandle;
|
||||||
|
import com.dfsek.terra.api.handle.WorldHandle;
|
||||||
|
import com.dfsek.terra.api.world.biome.PlatformBiome;
|
||||||
|
import com.dfsek.terra.minestom.biome.MinestomBiomeLoader;
|
||||||
|
import com.dfsek.terra.minestom.entity.MinestomEntityType;
|
||||||
|
import com.dfsek.terra.minestom.item.MinestomItemHandle;
|
||||||
|
import com.dfsek.terra.minestom.world.MinestomChunkGeneratorWrapper;
|
||||||
|
import com.dfsek.terra.minestom.world.MinestomWorldHandle;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
|
||||||
|
public final class MinestomPlatform extends AbstractPlatform {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(MinestomPlatform.class);
|
||||||
|
private static MinestomPlatform INSTANCE = null;
|
||||||
|
private final MinestomWorldHandle worldHandle = new MinestomWorldHandle();
|
||||||
|
private final MinestomItemHandle itemHandle = new MinestomItemHandle();
|
||||||
|
|
||||||
|
private MinestomPlatform() {
|
||||||
|
load();
|
||||||
|
getEventManager().callEvent(new PlatformInitializationEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(TypeRegistry registry) {
|
||||||
|
super.register(registry);
|
||||||
|
registry
|
||||||
|
.registerLoader(PlatformBiome.class, new MinestomBiomeLoader())
|
||||||
|
.registerLoader(EntityType.class, (TypeLoader<EntityType>) (annotatedType, o, configLoader, depthTracker) -> new MinestomEntityType((String) o))
|
||||||
|
.registerLoader(BlockState.class, (TypeLoader<BlockState>) (annotatedType, o, configLoader, depthTracker) -> worldHandle.createBlockState((String) o));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean reload() {
|
||||||
|
getTerraConfig().load(this);
|
||||||
|
getRawConfigRegistry().clear();
|
||||||
|
boolean succeed = getRawConfigRegistry().loadAll(this);
|
||||||
|
|
||||||
|
MinecraftServer.getInstanceManager().getInstances().forEach(world -> {
|
||||||
|
if(world.generator() instanceof MinestomChunkGeneratorWrapper wrapper) {
|
||||||
|
getConfigRegistry().get(wrapper.getPack().getRegistryKey()).ifPresent(pack -> {
|
||||||
|
wrapper.setPack(pack);
|
||||||
|
LOGGER.info("Replaced pack in chunk generator for instance {}", world.getUniqueId());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return succeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull WorldHandle getWorldHandle() {
|
||||||
|
return worldHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ItemHandle getItemHandle() {
|
||||||
|
return itemHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String platformName() {
|
||||||
|
return "Minestom";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull File getDataFolder() {
|
||||||
|
String pathName = System.getProperty("terra.datafolder");
|
||||||
|
if (pathName == null) pathName = "./terra/";
|
||||||
|
File file = new File(pathName);
|
||||||
|
if(!file.exists()) file.mkdirs();
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static MinestomPlatform getInstance() {
|
||||||
|
if(INSTANCE == null) {
|
||||||
|
INSTANCE = new MinestomPlatform();
|
||||||
|
}
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.dfsek.terra.minestom.api;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.block.entity.BlockEntity;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.BlockVec;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a factory interface for creating instances of BlockEntity
|
||||||
|
* at a specified BlockVec position. This is not implemented directly because
|
||||||
|
* Minestom does not define a way to build block entities out of the box.
|
||||||
|
*/
|
||||||
|
public interface BlockEntityFactory {
|
||||||
|
@Nullable BlockEntity createBlockEntity(BlockVec position);
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.dfsek.terra.minestom.api;
|
||||||
|
|
||||||
|
|
||||||
|
import net.minestom.server.entity.Entity;
|
||||||
|
import net.minestom.server.entity.EntityType;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows adding AI to generated entities using custom entity types
|
||||||
|
*/
|
||||||
|
public interface EntityFactory {
|
||||||
|
Entity createEntity(EntityType type);
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.dfsek.terra.minestom.biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.biome.PlatformBiome;
|
||||||
|
|
||||||
|
import net.minestom.server.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomBiome implements PlatformBiome {
|
||||||
|
private final Biome biome;
|
||||||
|
|
||||||
|
public MinestomBiome(Biome biome) { this.biome = biome; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome getHandle() {
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.dfsek.terra.minestom.biome;
|
||||||
|
|
||||||
|
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.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.registry.DynamicRegistry;
|
||||||
|
import net.minestom.server.utils.NamespaceID;
|
||||||
|
import net.minestom.server.world.biome.Biome;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.AnnotatedType;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomBiomeLoader implements TypeLoader<PlatformBiome> {
|
||||||
|
private final DynamicRegistry<Biome> biomeRegistry = MinecraftServer.getBiomeRegistry();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformBiome load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader,
|
||||||
|
DepthTracker depthTracker) throws LoadException {
|
||||||
|
String id = (String) o;
|
||||||
|
NamespaceID biomeID = NamespaceID.from(id);
|
||||||
|
Biome biome = biomeRegistry.get(biomeID);
|
||||||
|
if(biome == null) throw new LoadException("Biome %s does not exist in registry".formatted(id), depthTracker);
|
||||||
|
return new MinestomBiome(biome);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.dfsek.terra.minestom.block;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.block.entity.BlockEntity;
|
||||||
|
import com.dfsek.terra.minestom.api.BlockEntityFactory;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.BlockVec;
|
||||||
|
|
||||||
|
|
||||||
|
public class DefaultBlockEntityFactory implements BlockEntityFactory {
|
||||||
|
@Override
|
||||||
|
public BlockEntity createBlockEntity(BlockVec position) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
package com.dfsek.terra.minestom.block;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.block.BlockType;
|
||||||
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
|
import com.dfsek.terra.api.block.state.properties.Property;
|
||||||
|
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomBlockState implements BlockState {
|
||||||
|
private final Block block;
|
||||||
|
|
||||||
|
public MinestomBlockState(Block block) {
|
||||||
|
if(block == null) {
|
||||||
|
this.block = Block.AIR;
|
||||||
|
} else {
|
||||||
|
this.block = block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MinestomBlockState(String data) {
|
||||||
|
if(!data.contains("[")) {
|
||||||
|
block = Block.fromNamespaceId(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] split = data.split("\\[");
|
||||||
|
String namespaceId = split[0];
|
||||||
|
String properties = split[1].substring(0, split[1].length() - 1);
|
||||||
|
Block block = Block.fromNamespaceId(namespaceId);
|
||||||
|
HashMap<String, String> propertiesMap = new HashMap<>();
|
||||||
|
|
||||||
|
for(String property : properties.split(",")) {
|
||||||
|
String[] kv = property.split("=");
|
||||||
|
propertiesMap.put(kv[0].strip(), kv[1].strip());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert block != null;
|
||||||
|
this.block = block.withProperties(propertiesMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(BlockState other) {
|
||||||
|
return ((MinestomBlockState) other).block.compare(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Comparable<T>> boolean has(Property<T> property) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Comparable<T>> T get(Property<T> property) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Comparable<T>> BlockState set(Property<T> property, T value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockType getBlockType() {
|
||||||
|
return new MinestomBlockType(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAsString(boolean properties) {
|
||||||
|
String name = block.namespace().asString();
|
||||||
|
if(!properties || block.properties().isEmpty()) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
name += "[" + block.properties().entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).collect(
|
||||||
|
Collectors.joining(",")) + "]";
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAir() {
|
||||||
|
return block.isAir();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getHandle() {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(block.id());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.dfsek.terra.minestom.block;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.block.BlockType;
|
||||||
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
|
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomBlockType implements BlockType {
|
||||||
|
private final Block block;
|
||||||
|
|
||||||
|
public MinestomBlockType(Block block) {
|
||||||
|
this.block = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getDefaultState() {
|
||||||
|
return new MinestomBlockState(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSolid() {
|
||||||
|
return block.isSolid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWater() {
|
||||||
|
return block.isLiquid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getHandle() {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return block.id();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if(obj instanceof MinestomBlockType other) {
|
||||||
|
return block.id() == other.block.id();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package com.dfsek.terra.minestom.chunk;
|
||||||
|
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.chunk.generation.ProtoChunk;
|
||||||
|
import com.dfsek.terra.minestom.block.MinestomBlockState;
|
||||||
|
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.UnitModifier;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|
||||||
|
public class CachedChunk implements ProtoChunk {
|
||||||
|
private final int minHeight;
|
||||||
|
private final int maxHeight;
|
||||||
|
private final Block[][][] blocks;
|
||||||
|
|
||||||
|
public CachedChunk(int minHeight, int maxHeight) {
|
||||||
|
this.minHeight = minHeight;
|
||||||
|
this.maxHeight = maxHeight;
|
||||||
|
this.blocks = new Block[16][maxHeight - minHeight + 1][16];
|
||||||
|
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
for(int z = 0; z < 16; z++) {
|
||||||
|
for(int y = 0; y < maxHeight - minHeight + 1; y++) {
|
||||||
|
blocks[x][y][z] = Block.AIR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeRelative(UnitModifier modifier) {
|
||||||
|
modifier.setAllRelative((x, y, z) -> blocks[x][y][z]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlock(int x, int y, int z, @NotNull BlockState blockState) {
|
||||||
|
Block block = (Block) blockState.getHandle();
|
||||||
|
if(block == null) return;
|
||||||
|
blocks[x][y - minHeight][z] = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull BlockState getBlock(int x, int y, int z) {
|
||||||
|
return new MinestomBlockState(blocks[x][y - minHeight][z]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getHandle() {
|
||||||
|
return blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxHeight() {
|
||||||
|
return maxHeight;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.dfsek.terra.minestom.chunk;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.generic.pair.Pair;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.ServerWorld;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
||||||
|
|
||||||
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
|
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||||
|
import com.github.benmanes.caffeine.cache.stats.CacheStats;
|
||||||
|
import net.minestom.server.world.DimensionType;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
||||||
|
public class GeneratedChunkCache {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(GeneratedChunkCache.class);
|
||||||
|
private final LoadingCache<Pair<Integer, Integer>, CachedChunk> cache;
|
||||||
|
private final DimensionType dimensionType;
|
||||||
|
private final ChunkGenerator generator;
|
||||||
|
private final ServerWorld world;
|
||||||
|
private final BiomeProvider biomeProvider;
|
||||||
|
|
||||||
|
public GeneratedChunkCache(DimensionType dimensionType, ChunkGenerator generator, ServerWorld world) {
|
||||||
|
this.dimensionType = dimensionType;
|
||||||
|
this.generator = generator;
|
||||||
|
this.world = world;
|
||||||
|
this.biomeProvider = world.getBiomeProvider();
|
||||||
|
this.cache = Caffeine.newBuilder().maximumSize(128).recordStats().build(
|
||||||
|
(Pair<Integer, Integer> key) -> generateChunk(key.getLeft(), key.getRight()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private CachedChunk generateChunk(int x, int z) {
|
||||||
|
CachedChunk chunk = new CachedChunk(dimensionType.minY(), dimensionType.maxY());
|
||||||
|
generator.generateChunkData(chunk, world, biomeProvider, x, z);
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void displayStats() {
|
||||||
|
CacheStats stats = cache.stats();
|
||||||
|
log.info("Avg load time: {}ms | Hit rate: {}% | Load Count: {}", stats.averageLoadPenalty(), stats.hitRate() * 100,
|
||||||
|
stats.loadCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
public CachedChunk at(int x, int z) {
|
||||||
|
return cache.get(Pair.of(x, z));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.dfsek.terra.minestom.chunk;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
|
import com.dfsek.terra.api.world.ServerWorld;
|
||||||
|
import com.dfsek.terra.api.world.chunk.Chunk;
|
||||||
|
|
||||||
|
import com.dfsek.terra.minestom.block.MinestomBlockState;
|
||||||
|
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|
||||||
|
public class TerraMinestomChunk implements Chunk {
|
||||||
|
private net.minestom.server.instance.Chunk delegate;
|
||||||
|
private final ServerWorld world;
|
||||||
|
|
||||||
|
public TerraMinestomChunk(net.minestom.server.instance.Chunk delegate, ServerWorld world) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlock(int x, int y, int z, BlockState data, boolean physics) {
|
||||||
|
delegate.setBlock(x, y, z, (Block) data.getHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull BlockState getBlock(int x, int y, int z) {
|
||||||
|
return new MinestomBlockState(delegate.getBlock(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getX() {
|
||||||
|
return delegate.getChunkX();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getZ() {
|
||||||
|
return delegate.getChunkZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerWorld getWorld() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getHandle() {
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
public class DefaultEntityFactory implements EntityFactory {
|
||||||
|
@Override
|
||||||
|
public Entity createEntity(EntityType type) {
|
||||||
|
return new Entity(type);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
package com.dfsek.terra.minestom.entity;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.entity.Entity;
|
||||||
|
import com.dfsek.terra.api.entity.EntityType;
|
||||||
|
import com.dfsek.terra.api.util.vector.Vector3;
|
||||||
|
import com.dfsek.terra.api.world.ServerWorld;
|
||||||
|
import com.dfsek.terra.minestom.world.TerraMinestomWorld;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
|
||||||
|
|
||||||
|
public class DeferredMinestomEntity implements Entity {
|
||||||
|
private final EntityType type;
|
||||||
|
private double x;
|
||||||
|
private double y;
|
||||||
|
private double z;
|
||||||
|
private TerraMinestomWorld world;
|
||||||
|
|
||||||
|
public DeferredMinestomEntity(double x, double y, double z, EntityType type, TerraMinestomWorld world) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.type = type;
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3 position() {
|
||||||
|
return Vector3.of(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pos pos() {
|
||||||
|
return new Pos(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void position(Vector3 position) {
|
||||||
|
x = position.getX();
|
||||||
|
y = position.getY();
|
||||||
|
z = position.getZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void world(ServerWorld world) {
|
||||||
|
this.world = (TerraMinestomWorld) world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerWorld world() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getHandle() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void spawn() {
|
||||||
|
int chunkX = (int) x >> 4;
|
||||||
|
int chunkZ = (int) z >> 4;
|
||||||
|
|
||||||
|
if(!world.getHandle().isChunkLoaded(chunkX, chunkZ)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MinestomEntity.spawn(x, y, z, type, world);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.dfsek.terra.minestom.entity;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.entity.EntityType;
|
||||||
|
import com.dfsek.terra.api.util.vector.Vector3;
|
||||||
|
import com.dfsek.terra.api.world.ServerWorld;
|
||||||
|
|
||||||
|
import com.dfsek.terra.minestom.MinestomAdapter;
|
||||||
|
import com.dfsek.terra.minestom.world.TerraMinestomWorld;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.entity.Entity;
|
||||||
|
import net.minestom.server.instance.Instance;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomEntity implements com.dfsek.terra.api.entity.Entity {
|
||||||
|
private final Entity delegate;
|
||||||
|
private final TerraMinestomWorld world;
|
||||||
|
|
||||||
|
public MinestomEntity(Entity delegate, TerraMinestomWorld world) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3 position() {
|
||||||
|
return MinestomAdapter.adapt(delegate.getPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void position(Vector3 position) {
|
||||||
|
delegate.teleport(MinestomAdapter.adapt(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void world(ServerWorld world) {
|
||||||
|
delegate.setInstance(((TerraMinestomWorld) world).getHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerWorld world() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getHandle() {
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MinestomEntity spawn(double x, double y, double z, EntityType type, TerraMinestomWorld world) {
|
||||||
|
Instance instance = world.getHandle();
|
||||||
|
Entity entity = world.getEntityFactory().createEntity(((MinestomEntityType) type).getHandle());
|
||||||
|
entity.setInstance(instance, new Pos(x, y, z));
|
||||||
|
return new MinestomEntity(entity, world);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.dfsek.terra.minestom.entity;
|
||||||
|
|
||||||
|
|
||||||
|
import net.minestom.server.entity.EntityType;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomEntityType implements com.dfsek.terra.api.entity.EntityType {
|
||||||
|
private final EntityType delegate;
|
||||||
|
|
||||||
|
public MinestomEntityType(String id) {
|
||||||
|
delegate = EntityType.fromNamespaceId(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityType getHandle() {
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.dfsek.terra.minestom.item;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.inventory.ItemStack;
|
||||||
|
import com.dfsek.terra.api.inventory.item.Enchantment;
|
||||||
|
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
import net.minestom.server.utils.NamespaceID;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomEnchantment implements Enchantment {
|
||||||
|
private final net.minestom.server.item.enchant.Enchantment delegate;
|
||||||
|
private final String id;
|
||||||
|
|
||||||
|
public MinestomEnchantment(net.minestom.server.item.enchant.Enchantment delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
id = Objects.requireNonNull(delegate.registry()).raw();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MinestomEnchantment(String id) {
|
||||||
|
this.delegate = MinecraftServer.getEnchantmentRegistry().get(NamespaceID.from(id));
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canEnchantItem(ItemStack itemStack) {
|
||||||
|
return delegate.supportedItems().contains((Material) itemStack.getType().getHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean conflictsWith(Enchantment other) {
|
||||||
|
return delegate.exclusiveSet().contains(NamespaceID.from(((MinestomEnchantment) other).id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxLevel() {
|
||||||
|
return delegate.maxLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.minestom.server.item.enchant.Enchantment getHandle() {
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.dfsek.terra.minestom.item;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.handle.ItemHandle;
|
||||||
|
import com.dfsek.terra.api.inventory.Item;
|
||||||
|
import com.dfsek.terra.api.inventory.item.Enchantment;
|
||||||
|
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomItemHandle implements ItemHandle {
|
||||||
|
@Override
|
||||||
|
public Item createItem(String data) {
|
||||||
|
return new MinestomMaterial(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Enchantment getEnchantment(String id) {
|
||||||
|
return new MinestomEnchantment(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Enchantment> getEnchantments() {
|
||||||
|
return MinecraftServer.getEnchantmentRegistry().values().stream().map(MinestomEnchantment::new).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.dfsek.terra.minestom.item;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.inventory.item.Enchantment;
|
||||||
|
import com.dfsek.terra.api.inventory.item.ItemMeta;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomItemMeta implements ItemMeta {
|
||||||
|
private final HashMap<Enchantment, Integer> enchantments;
|
||||||
|
|
||||||
|
public MinestomItemMeta(HashMap<Enchantment, Integer> enchantments) {
|
||||||
|
this.enchantments = enchantments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addEnchantment(Enchantment enchantment, int level) {
|
||||||
|
enchantments.put(enchantment, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Enchantment, Integer> getEnchantments() {
|
||||||
|
return enchantments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getHandle() {
|
||||||
|
return enchantments;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.dfsek.terra.minestom.item;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.inventory.Item;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.inventory.item.Enchantment;
|
||||||
|
import com.dfsek.terra.api.inventory.item.ItemMeta;
|
||||||
|
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.item.ItemComponent;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.item.component.EnchantmentList;
|
||||||
|
import net.minestom.server.registry.DynamicRegistry;
|
||||||
|
import net.minestom.server.registry.DynamicRegistry.Key;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomItemStack implements com.dfsek.terra.api.inventory.ItemStack {
|
||||||
|
private ItemStack base;
|
||||||
|
|
||||||
|
public MinestomItemStack(net.minestom.server.item.@NotNull ItemStack base) {
|
||||||
|
this.base = base;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getHandle() {
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAmount() {
|
||||||
|
return base.amount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAmount(int i) {
|
||||||
|
base = base.withAmount(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Item getType() {
|
||||||
|
return new MinestomMaterial(base.material());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemMeta getItemMeta() {
|
||||||
|
HashMap<Enchantment, Integer> enchantments = new HashMap<>();
|
||||||
|
EnchantmentList enchantmentList = base.get(ItemComponent.ENCHANTMENTS);
|
||||||
|
if(enchantmentList != null) {
|
||||||
|
enchantmentList.enchantments().forEach((enchantmentKey, integer) -> {
|
||||||
|
enchantments.put(
|
||||||
|
new MinestomEnchantment(Objects.requireNonNull(MinecraftServer.getEnchantmentRegistry().get(enchantmentKey))), integer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return new MinestomItemMeta(enchantments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setItemMeta(ItemMeta meta) {
|
||||||
|
HashMap<Key<net.minestom.server.item.enchant.Enchantment>, Integer> enchantments = new HashMap<>();
|
||||||
|
DynamicRegistry<net.minestom.server.item.enchant.Enchantment> registry = MinecraftServer.getEnchantmentRegistry();
|
||||||
|
meta.getEnchantments().forEach((key, value) -> {
|
||||||
|
MinestomEnchantment enchantment = (MinestomEnchantment) key;
|
||||||
|
enchantments.put(registry.getKey(enchantment.getHandle()), value);
|
||||||
|
});
|
||||||
|
|
||||||
|
EnchantmentList list = new EnchantmentList(enchantments);
|
||||||
|
base = base.with(ItemComponent.ENCHANTMENTS, list);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.dfsek.terra.minestom.item;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.inventory.Item;
|
||||||
|
import com.dfsek.terra.api.inventory.ItemStack;
|
||||||
|
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomMaterial implements Item {
|
||||||
|
private final Material delegate;
|
||||||
|
|
||||||
|
public MinestomMaterial(Material delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MinestomMaterial(String id) {
|
||||||
|
this.delegate = Material.fromNamespaceId(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack newItemStack(int amount) {
|
||||||
|
return new MinestomItemStack(net.minestom.server.item.ItemStack.builder(delegate).amount(amount).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getMaxDurability() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Material getHandle() {
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
package com.dfsek.terra.minestom.world;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
|
||||||
|
import com.dfsek.terra.api.world.chunk.generation.util.GeneratorWrapper;
|
||||||
|
import com.dfsek.terra.minestom.chunk.CachedChunk;
|
||||||
|
import com.dfsek.terra.minestom.chunk.GeneratedChunkCache;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
import net.minestom.server.instance.generator.Generator;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrapper {
|
||||||
|
private final GeneratedChunkCache cache;
|
||||||
|
private ChunkGenerator generator;
|
||||||
|
private final TerraMinestomWorld world;
|
||||||
|
private ConfigPack pack;
|
||||||
|
|
||||||
|
public MinestomChunkGeneratorWrapper(ChunkGenerator generator, TerraMinestomWorld world, ConfigPack pack) {
|
||||||
|
this.generator = generator;
|
||||||
|
this.world = world;
|
||||||
|
this.pack = pack;
|
||||||
|
this.cache = new GeneratedChunkCache(world.getDimensionType(), generator, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChunkGenerator getGenerator() {
|
||||||
|
return generator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(@NotNull GenerationUnit unit) {
|
||||||
|
Point start = unit.absoluteStart();
|
||||||
|
int x = start.chunkX();
|
||||||
|
int z = start.chunkZ();
|
||||||
|
CachedChunk chunk = cache.at(x, z);
|
||||||
|
chunk.writeRelative(unit.modifier());
|
||||||
|
|
||||||
|
unit.fork(setter -> {
|
||||||
|
MinestomProtoWorld protoWorld = new MinestomProtoWorld(cache, x, z, world, setter);
|
||||||
|
|
||||||
|
for(GenerationStage stage : world.getPack().getStages()) {
|
||||||
|
stage.populate(protoWorld);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigPack getPack() {
|
||||||
|
return pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPack(ConfigPack pack) {
|
||||||
|
this.pack = pack;
|
||||||
|
this.generator = pack.getGeneratorProvider().newInstance(pack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void displayStats() {
|
||||||
|
cache.displayStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkGenerator getHandle() {
|
||||||
|
return generator;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
package com.dfsek.terra.minestom.world;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.block.entity.BlockEntity;
|
||||||
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.api.entity.Entity;
|
||||||
|
import com.dfsek.terra.api.entity.EntityType;
|
||||||
|
import com.dfsek.terra.api.world.ServerWorld;
|
||||||
|
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.minestom.chunk.CachedChunk;
|
||||||
|
import com.dfsek.terra.minestom.chunk.GeneratedChunkCache;
|
||||||
|
|
||||||
|
import com.dfsek.terra.minestom.entity.DeferredMinestomEntity;
|
||||||
|
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.block.Block.Setter;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomProtoWorld implements ProtoWorld {
|
||||||
|
private final GeneratedChunkCache cache;
|
||||||
|
private final int x;
|
||||||
|
private final int z;
|
||||||
|
private final TerraMinestomWorld world;
|
||||||
|
private final Setter modifier;
|
||||||
|
|
||||||
|
public MinestomProtoWorld(GeneratedChunkCache cache, int x, int z, TerraMinestomWorld world, Setter modifier) {
|
||||||
|
this.cache = cache;
|
||||||
|
this.x = x;
|
||||||
|
this.z = z;
|
||||||
|
this.world = world;
|
||||||
|
this.modifier = modifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int centerChunkX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int centerChunkZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerWorld getWorld() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlockState(int x, int y, int z, BlockState data, boolean physics) {
|
||||||
|
modifier.setBlock(x, y, z, (Block) data.getHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity spawnEntity(double x, double y, double z, EntityType entityType) {
|
||||||
|
TerraMinestomWorld world = this.world;
|
||||||
|
DeferredMinestomEntity entity = new DeferredMinestomEntity(x, y, z, entityType, world);
|
||||||
|
world.enqueue(entity.pos(), (chunk) -> entity.spawn());
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlockState(int x, int y, int z) {
|
||||||
|
int chunkX = x >> 4;
|
||||||
|
int chunkZ = z >> 4;
|
||||||
|
CachedChunk chunk = cache.at(chunkX, chunkZ);
|
||||||
|
return chunk.getBlock(x & 15, y, z & 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockEntity getBlockEntity(int x, int y, int z) {
|
||||||
|
return world.getBlockEntity(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkGenerator getGenerator() {
|
||||||
|
return world.getGenerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeProvider getBiomeProvider() {
|
||||||
|
return world.getBiomeProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigPack getPack() {
|
||||||
|
return world.getPack();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getSeed() {
|
||||||
|
return world.getSeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxHeight() {
|
||||||
|
return world.getMaxHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinHeight() {
|
||||||
|
return world.getMinHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getHandle() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.dfsek.terra.minestom.world;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
|
import com.dfsek.terra.api.entity.EntityType;
|
||||||
|
import com.dfsek.terra.api.handle.WorldHandle;
|
||||||
|
|
||||||
|
import com.dfsek.terra.minestom.block.MinestomBlockState;
|
||||||
|
import com.dfsek.terra.minestom.entity.MinestomEntityType;
|
||||||
|
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|
||||||
|
public class MinestomWorldHandle implements WorldHandle {
|
||||||
|
private static final MinestomBlockState AIR = new MinestomBlockState(Block.AIR);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull BlockState createBlockState(@NotNull String data) {
|
||||||
|
return new MinestomBlockState(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull BlockState air() {
|
||||||
|
return AIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull EntityType getEntity(@NotNull String id) {
|
||||||
|
return new MinestomEntityType(id);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
package com.dfsek.terra.minestom.world;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.block.entity.BlockEntity;
|
||||||
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.api.entity.Entity;
|
||||||
|
import com.dfsek.terra.api.entity.EntityType;
|
||||||
|
import com.dfsek.terra.api.world.ServerWorld;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
import com.dfsek.terra.api.world.chunk.Chunk;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.info.WorldProperties;
|
||||||
|
|
||||||
|
import com.dfsek.terra.minestom.api.BlockEntityFactory;
|
||||||
|
import com.dfsek.terra.minestom.api.EntityFactory;
|
||||||
|
import com.dfsek.terra.minestom.block.MinestomBlockState;
|
||||||
|
import com.dfsek.terra.minestom.entity.MinestomEntity;
|
||||||
|
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.coordinate.BlockVec;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.Instance;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.world.DimensionType;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
|
||||||
|
public final class TerraMinestomWorld implements ServerWorld, WorldProperties {
|
||||||
|
private final Instance instance;
|
||||||
|
private final ConfigPack pack;
|
||||||
|
private final long seed;
|
||||||
|
private final DimensionType dimensionType;
|
||||||
|
private final MinestomChunkGeneratorWrapper wrapper;
|
||||||
|
private final EntityFactory entityFactory;
|
||||||
|
private final BlockEntityFactory blockEntityFactory;
|
||||||
|
|
||||||
|
public TerraMinestomWorld(Instance instance, ConfigPack pack, long seed, EntityFactory entityFactory,
|
||||||
|
BlockEntityFactory blockEntityFactory) {
|
||||||
|
this.instance = instance;
|
||||||
|
this.pack = pack;
|
||||||
|
this.seed = seed;
|
||||||
|
|
||||||
|
this.dimensionType = MinecraftServer.getDimensionTypeRegistry().get(instance.getDimensionType());
|
||||||
|
this.blockEntityFactory = blockEntityFactory;
|
||||||
|
|
||||||
|
this.wrapper = new MinestomChunkGeneratorWrapper(pack.getGeneratorProvider().newInstance(pack), this, pack);
|
||||||
|
this.entityFactory = entityFactory;
|
||||||
|
|
||||||
|
instance.setGenerator(this.wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Chunk getChunkAt(int x, int z) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlockState(int x, int y, int z, BlockState data, boolean physics) {
|
||||||
|
instance.setBlock(x, y, z, (Block) data.getHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity spawnEntity(double x, double y, double z, EntityType entityType) {
|
||||||
|
return MinestomEntity.spawn(x, y, z, entityType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void displayStats() {
|
||||||
|
wrapper.displayStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlockState(int x, int y, int z) {
|
||||||
|
return new MinestomBlockState(instance.getBlock(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockEntity getBlockEntity(int x, int y, int z) {
|
||||||
|
return blockEntityFactory.createBlockEntity(new BlockVec(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkGenerator getGenerator() {
|
||||||
|
return wrapper.getGenerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeProvider getBiomeProvider() {
|
||||||
|
return pack.getBiomeProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigPack getPack() {
|
||||||
|
return pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getSeed() {
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxHeight() {
|
||||||
|
return dimensionType.maxY();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinHeight() {
|
||||||
|
return dimensionType.minY();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Instance getHandle() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DimensionType getDimensionType() {
|
||||||
|
return dimensionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityFactory getEntityFactory() {
|
||||||
|
return entityFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enqueue(Point position, Consumer<net.minestom.server.instance.Chunk> action) {
|
||||||
|
instance.loadChunk(position.chunkX(), position.chunkZ()).thenAccept(action);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package com.dfsek.terra.minestom.world;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||||
|
|
||||||
|
import com.dfsek.terra.minestom.MinestomPlatform;
|
||||||
|
import com.dfsek.terra.minestom.api.BlockEntityFactory;
|
||||||
|
import com.dfsek.terra.minestom.api.EntityFactory;
|
||||||
|
import com.dfsek.terra.minestom.block.DefaultBlockEntityFactory;
|
||||||
|
import com.dfsek.terra.minestom.entity.DefaultEntityFactory;
|
||||||
|
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.instance.Instance;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
|
||||||
|
public class TerraMinestomWorldBuilder {
|
||||||
|
private final Instance instance;
|
||||||
|
private ConfigPack pack;
|
||||||
|
private long seed = new Random().nextLong();
|
||||||
|
private EntityFactory entityFactory = new DefaultEntityFactory();
|
||||||
|
private BlockEntityFactory blockEntityFactory = new DefaultBlockEntityFactory();
|
||||||
|
|
||||||
|
private TerraMinestomWorldBuilder(Instance instance) { this.instance = instance; }
|
||||||
|
|
||||||
|
public static TerraMinestomWorldBuilder from(Instance instance) {
|
||||||
|
return new TerraMinestomWorldBuilder(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TerraMinestomWorldBuilder builder() {
|
||||||
|
return new TerraMinestomWorldBuilder(MinecraftServer.getInstanceManager().createInstanceContainer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerraMinestomWorldBuilder pack(ConfigPack pack) {
|
||||||
|
this.pack = pack;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerraMinestomWorldBuilder packById(String id) {
|
||||||
|
this.pack = MinestomPlatform.getInstance().getConfigRegistry().getByID(id).orElseThrow();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerraMinestomWorldBuilder findPack(Function<CheckedRegistry<ConfigPack>, ConfigPack> fn) {
|
||||||
|
this.pack = fn.apply(MinestomPlatform.getInstance().getConfigRegistry());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerraMinestomWorldBuilder defaultPack() {
|
||||||
|
return this.packById("OVERWORLD");
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerraMinestomWorldBuilder seed(long seed) {
|
||||||
|
this.seed = seed;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerraMinestomWorldBuilder entityFactory(EntityFactory factory) {
|
||||||
|
this.entityFactory = factory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerraMinestomWorldBuilder blockEntityFactory(BlockEntityFactory factory) {
|
||||||
|
this.blockEntityFactory = factory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerraMinestomWorld attach() {
|
||||||
|
return new TerraMinestomWorld(instance, pack, seed, entityFactory, blockEntityFactory);
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ includeImmediateChildren(file("platforms"), "platform")
|
|||||||
includeImmediateChildren(file("platforms/bukkit/nms"), "Bukkit NMS")
|
includeImmediateChildren(file("platforms/bukkit/nms"), "Bukkit NMS")
|
||||||
|
|
||||||
include(":platforms:bukkit:common")
|
include(":platforms:bukkit:common")
|
||||||
|
include(":platforms:minestom:example")
|
||||||
|
|
||||||
pluginManagement {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user