diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/MinestomAdapter.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/MinestomAdapter.java new file mode 100644 index 000000000..697997c0b --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/MinestomAdapter.java @@ -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()); + } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/EntityFactory.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/EntityFactory.java new file mode 100644 index 000000000..5cfbecd8d --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/EntityFactory.java @@ -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); +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/DefaultEntityFactory.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/DefaultEntityFactory.java new file mode 100644 index 000000000..23226fc99 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/DefaultEntityFactory.java @@ -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); + } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/DeferredMinestomEntity.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/DeferredMinestomEntity.java new file mode 100644 index 000000000..6dfdf5b52 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/DeferredMinestomEntity.java @@ -0,0 +1,62 @@ +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; + + +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); + } + + @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); + } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/MinestomEntity.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/MinestomEntity.java new file mode 100644 index 000000000..c46a6a1d3 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/MinestomEntity.java @@ -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); + } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/MinestomEntityType.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/MinestomEntityType.java new file mode 100644 index 000000000..60fbac5d9 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/MinestomEntityType.java @@ -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; + } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomProtoWorld.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomProtoWorld.java index 628dcf990..d267d9900 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomProtoWorld.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomProtoWorld.java @@ -11,6 +11,8 @@ import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; import com.dfsek.terra.api.world.chunk.generation.ProtoWorld; 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; @@ -62,7 +64,10 @@ public class MinestomProtoWorld implements ProtoWorld { @Override public Entity spawnEntity(double x, double y, double z, EntityType entityType) { - return null; + TerraMinestomWorld world = (TerraMinestomWorld) this.world; + DeferredMinestomEntity entity = new DeferredMinestomEntity(x, y, z, entityType, world); + world.enqueueEntitySpawn(entity); + return entity; } @Override diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomWorldHandle.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomWorldHandle.java index eb5731bb4..98429ab6d 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomWorldHandle.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomWorldHandle.java @@ -5,6 +5,8 @@ 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; @@ -24,6 +26,6 @@ public class MinestomWorldHandle implements WorldHandle { @Override public @NotNull EntityType getEntity(@NotNull String id) { - return null; + return new MinestomEntityType(id); } } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java index aac669a32..5066b05cb 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java @@ -5,6 +5,7 @@ import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.entity.Entity; import com.dfsek.terra.api.entity.EntityType; +import com.dfsek.terra.api.util.generic.pair.Pair; import com.dfsek.terra.api.world.ServerWorld; import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.chunk.Chunk; @@ -13,10 +14,19 @@ import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; import com.dfsek.terra.api.world.info.WorldProperties; +import com.dfsek.terra.minestom.api.EntityFactory; +import com.dfsek.terra.minestom.block.MinestomBlockState; +import com.dfsek.terra.minestom.entity.DeferredMinestomEntity; +import com.dfsek.terra.minestom.entity.MinestomEntity; + import net.minestom.server.MinecraftServer; import net.minestom.server.instance.Instance; +import net.minestom.server.instance.block.Block; import net.minestom.server.world.DimensionType; +import java.util.ArrayList; +import java.util.HashMap; + public final class TerraMinestomWorld implements ServerWorld, WorldProperties { private final Instance instance; @@ -24,8 +34,9 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties { private final long seed; private final DimensionType dimensionType; private final MinestomChunkGeneratorWrapper wrapper; + private final EntityFactory factory; - public TerraMinestomWorld(Instance instance, ConfigPack pack, long seed) { + public TerraMinestomWorld(Instance instance, ConfigPack pack, long seed, EntityFactory factory) { this.instance = instance; this.pack = pack; this.seed = seed; @@ -36,6 +47,7 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties { pack.getGeneratorProvider().newInstance(pack), this ); + this.factory = factory; instance.setGenerator(this.wrapper); } @@ -47,17 +59,17 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties { @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 null; + return MinestomEntity.spawn(x, y, z, entityType, this); } @Override public BlockState getBlockState(int x, int y, int z) { - return null; + return new MinestomBlockState(instance.getBlock(x, y, z)); } @Override @@ -96,11 +108,21 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties { } @Override - public Object getHandle() { + public Instance getHandle() { return instance; } public DimensionType getDimensionType() { return dimensionType; } + + public EntityFactory getEntityFactory() { + return factory; + } + + public void enqueueEntitySpawn(DeferredMinestomEntity deferredMinestomEntity) { + int chunkX = deferredMinestomEntity.position().getBlockX() >> 4; + int chunkZ = deferredMinestomEntity.position().getBlockZ() >> 4; + instance.loadChunk(chunkX, chunkZ).thenAccept(chunk -> deferredMinestomEntity.spawn()); + } } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java index 8b70b3a0f..5a018ef2d 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java @@ -5,6 +5,8 @@ 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.EntityFactory; +import com.dfsek.terra.minestom.entity.DefaultEntityFactory; import net.minestom.server.MinecraftServer; import net.minestom.server.instance.Instance; @@ -16,6 +18,7 @@ public class TerraMinestomWorldBuilder { private final Instance instance; private ConfigPack pack; private long seed = new Random().nextLong(); + private EntityFactory factory = new DefaultEntityFactory(); private TerraMinestomWorldBuilder(Instance instance) { this.instance = instance; } @@ -56,7 +59,12 @@ public class TerraMinestomWorldBuilder { return this; } + public TerraMinestomWorldBuilder entityFactory(EntityFactory factory) { + this.factory = factory; + return this; + } + public TerraMinestomWorld attach() { - return new TerraMinestomWorld(instance, pack, seed); + return new TerraMinestomWorld(instance, pack, seed, factory); } }