diff --git a/block/README.md b/block/README.md new file mode 100644 index 0000000..9e4406f --- /dev/null +++ b/block/README.md @@ -0,0 +1,12 @@ +# 🧱 Block Module + +This module provides a collection of **block handlers** for different block types. + +> [!CAUTION] +> This module is **data-only**. +> It loads and registers block states but does **not** implement placement, interaction, or gameplay logic. +> Such behavior must be handled in other modules. + +> [!NOTE] +> This module is designed to be **extensible**. +> Additional block handlers and state definitions can be implemented as needed, without altering the existing structure. diff --git a/block/build.gradle.kts b/block/build.gradle.kts new file mode 100644 index 0000000..a63694e --- /dev/null +++ b/block/build.gradle.kts @@ -0,0 +1,34 @@ +plugins { + `java-library` +} + +group = "net.theevilreaper" +version = "0.0.1" + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(25)) + } +} + +dependencies { + implementation(platform(libs.mycelium.bom)) + compileOnly(libs.minestom) + + testImplementation(libs.minestom) + testImplementation(libs.cyano) + testImplementation(libs.junit.api) + testImplementation(libs.junit.params) + testImplementation(libs.junit.platform.launcher) + testRuntimeOnly(libs.junit.engine) +} + +tasks { + test { + jvmArgs("-Dminestom.inside-test=true") + useJUnitPlatform() + testLogging { + events("passed", "skipped", "failed") + } + } +} \ No newline at end of file diff --git a/block/src/main/java/net/theevilreaper/bounce/block/BlockLoader.java b/block/src/main/java/net/theevilreaper/bounce/block/BlockLoader.java new file mode 100644 index 0000000..0f7d578 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/BlockLoader.java @@ -0,0 +1,77 @@ +package net.theevilreaper.bounce.block; + +import net.minestom.server.instance.block.BlockManager; +import org.jetbrains.annotations.Contract; + +import net.theevilreaper.bounce.block.type.lantern.LanternBlockFactory.Type; + +public sealed interface BlockLoader permits BlockLoaderBuilder { + + /** + * Creates a new {@link BlockLoaderBuilder} for the specified block manager. + * + * @param blockManager the block manager to use + * @return a new {@link BlockLoaderBuilder} instance + */ + @Contract(value = "_ -> new", pure = true) + static BlockLoader builder(BlockManager blockManager) { + return new BlockLoaderBuilder(blockManager); + } + + BlockLoader torch(); + + BlockLoader fenceGate(); + + /** + * Registers a new torch variant. + * + * @param type the type of the torch variant + * @return this builder instance for chaining + */ + BlockLoader lanternVariant(Type type); + + /** + * Registers a new head variant. + * + * @return this builder instance for chaining + */ + BlockLoader playerHead(); + + /** + * Registers a new wall head variant. + * + * @return this builder instance for chaining + */ + BlockLoader playerWallHead(); + + /** + * Registers a new barrel variant. + * + * @return this builder instance for chaining + */ + BlockLoader barrel(); + + /** + * Registers a new iron bars variant. + * + * @return this builder instance for chaining + */ + BlockLoader ironBars(); + + /** + * Registers a new grindstone variant. + * + * @return this builder instance for chaining + */ + BlockLoader grindStone(); + + BlockLoader candle(); + + BlockLoader ironChain(); + + BlockLoader stairs(); + + BlockLoader slab(); + + BlockLoader flowerPot(); +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/BlockLoaderBuilder.java b/block/src/main/java/net/theevilreaper/bounce/block/BlockLoaderBuilder.java new file mode 100644 index 0000000..1744e28 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/BlockLoaderBuilder.java @@ -0,0 +1,147 @@ +package net.theevilreaper.bounce.block; + +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.instance.block.BlockManager; +import net.theevilreaper.bounce.block.type.BambooPotBlockHandler; +import net.theevilreaper.bounce.block.type.BarrelBlockHandler; +import net.theevilreaper.bounce.block.type.CandleBlockHandler; +import net.theevilreaper.bounce.block.type.GrindstoneBlockHandler; +import net.theevilreaper.bounce.block.type.IronChainBlockHandler; +import net.theevilreaper.bounce.block.type.SlabBlockHandler; +import net.theevilreaper.bounce.block.type.TorchBlockHandler; +import net.theevilreaper.bounce.block.type.gates.GateBlockHandler; +import net.theevilreaper.bounce.block.type.grates.IronGrateBlockHandler; +import net.theevilreaper.bounce.block.type.lantern.LanternBlockFactory; +import net.theevilreaper.bounce.block.type.player.PlayerHeadBlockHandler; +import net.theevilreaper.bounce.block.type.player.PlayerWallHeadBlockHandler; +import net.theevilreaper.bounce.block.type.stairs.StairsBlockHandler; + +public final class BlockLoaderBuilder implements BlockLoader { + + private final BlockManager blockManager; + + BlockLoaderBuilder(BlockManager blockManager) { + this.blockManager = blockManager; + } + + /** + * {@inheritDoc} + */ + @Override + public BlockLoader lanternVariant(LanternBlockFactory.Type type) { + blockManager.registerHandler(type.getBlock().key(), () -> LanternBlockFactory.create(type)); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public BlockLoader playerHead() { + BlockHandler blockHandler = new PlayerHeadBlockHandler(); + blockManager.registerHandler(blockHandler.getKey(), () -> blockHandler); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public BlockLoader playerWallHead() { + BlockHandler blockHandler = new PlayerWallHeadBlockHandler(); + blockManager.registerHandler(blockHandler.getKey(), () -> blockHandler); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public BlockLoader barrel() { + BlockHandler blockHandler = new BarrelBlockHandler(); + blockManager.registerHandler(blockHandler.getKey(), () -> blockHandler); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public BlockLoader ironBars() { + BlockHandler blockHandler = new IronGrateBlockHandler(); + blockManager.registerHandler(blockHandler.getKey(), () -> blockHandler); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public BlockLoader grindStone() { + BlockHandler blockHandler = new GrindstoneBlockHandler(); + blockManager.registerHandler(blockHandler.getKey(), () -> blockHandler); + return this; + } + + @Override + public BlockLoader ironChain() { + BlockHandler blockHandler = new IronChainBlockHandler(); + blockManager.registerHandler(blockHandler.getKey(), () -> blockHandler); + return this; + } + + @Override + public BlockLoader stairs() { + blockManager.registerHandler(Block.OAK_STAIRS.key(), () -> new StairsBlockHandler(Block.OAK_STAIRS)); + blockManager.registerHandler(Block.SPRUCE_STAIRS.key(), () -> new StairsBlockHandler(Block.OAK_STAIRS)); + blockManager.registerHandler(Block.PALE_OAK_STAIRS.key(), () -> new StairsBlockHandler(Block.OAK_STAIRS)); + return this; + } + + @Override + public BlockLoader candle() { + BlockHandler blockHandler = new CandleBlockHandler(Block.RED_CANDLE.key()); + blockManager.registerHandler(blockHandler.getKey(), () -> blockHandler); + return this; + } + + @Override + public BlockLoader torch() { + BlockHandler blockHandler = new TorchBlockHandler(); + blockManager.registerHandler(blockHandler.getKey(), () -> blockHandler); + return this; + } + + @Override + public BlockLoader fenceGate() { + blockManager.registerHandler(Block.OAK_FENCE_GATE.key(), () -> new GateBlockHandler(Block.OAK_PLANKS.key())); + blockManager.registerHandler(Block.BIRCH_FENCE_GATE.key(), () -> new GateBlockHandler(Block.OAK_PLANKS.key())); + blockManager.registerHandler(Block.SPRUCE_FENCE_GATE.key(), () -> new GateBlockHandler(Block.OAK_PLANKS.key())); + blockManager.registerHandler(Block.JUNGLE_FENCE_GATE.key(), () -> new GateBlockHandler(Block.OAK_PLANKS.key())); + blockManager.registerHandler(Block.ACACIA_FENCE_GATE.key(), () -> new GateBlockHandler(Block.OAK_PLANKS.key())); + blockManager.registerHandler(Block.PALE_OAK_FENCE_GATE.key(), () -> new GateBlockHandler(Block.OAK_PLANKS.key())); + return this; + } + + @Override + public BlockLoader slab() { + blockManager.registerHandler( + Block.OAK_SLAB.key(), () -> new SlabBlockHandler(Block.OAK_SLAB.key()) + ); + blockManager.registerHandler( + Block.OAK_SLAB.key(), () -> new SlabBlockHandler(Block.SPRUCE_SLAB.key()) + ); + blockManager.registerHandler( + Block.OAK_SLAB.key(), () -> new SlabBlockHandler(Block.WARPED_SLAB.key()) + ); + return this; + + } + + @Override + public BlockLoader flowerPot() { + blockManager.registerHandler(Block.POTTED_BAMBOO.key(), BambooPotBlockHandler::new); + return this; + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/package-info.java b/block/src/main/java/net/theevilreaper/bounce/block/package-info.java new file mode 100644 index 0000000..3bbc072 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.bounce.block; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/BambooPotBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/BambooPotBlockHandler.java new file mode 100644 index 0000000..b1edfac --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/BambooPotBlockHandler.java @@ -0,0 +1,23 @@ +package net.theevilreaper.bounce.block.type; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; + +import java.util.Collection; +import java.util.List; + +public class BambooPotBlockHandler implements BlockHandler { + @Override + public Key getKey() { + return Block.POTTED_BAMBOO.key(); + } + + @Override + public Collection> getBlockEntityTags() { + return List.of( + Tag.Integer("rotating") + ); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/BarrelBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/BarrelBlockHandler.java new file mode 100644 index 0000000..377dcc6 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/BarrelBlockHandler.java @@ -0,0 +1,25 @@ +package net.theevilreaper.bounce.block.type; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; + +import java.util.Collection; +import java.util.List; + +public class BarrelBlockHandler implements BlockHandler { + + @Override + public Key getKey() { + return Block.BARREL.key(); + } + + @Override + public Collection> getBlockEntityTags() { + return List.of( + Tag.String("facing"), + Tag.Boolean("open") + ); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/CandleBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/CandleBlockHandler.java new file mode 100644 index 0000000..0a341c6 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/CandleBlockHandler.java @@ -0,0 +1,31 @@ +package net.theevilreaper.bounce.block.type; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; + +import java.util.Collection; +import java.util.List; + +public class CandleBlockHandler implements BlockHandler { + + private final Key key; + + public CandleBlockHandler(Key key) { + this.key = key; + } + + @Override + public Key getKey() { + return this.key; + } + + @Override + public Collection> getBlockEntityTags() { + return List.of( + Tag.Integer("candles"), + Tag.Boolean("lit"), + Tag.Boolean("waterlogged") + ); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/GrindstoneBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/GrindstoneBlockHandler.java new file mode 100644 index 0000000..90362c8 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/GrindstoneBlockHandler.java @@ -0,0 +1,25 @@ +package net.theevilreaper.bounce.block.type; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; + +import java.util.Collection; +import java.util.List; + +public class GrindstoneBlockHandler implements BlockHandler { + + @Override + public Key getKey() { + return Block.GRINDSTONE.key(); + } + + @Override + public Collection> getBlockEntityTags() { + return List.of( + Tag.String("face"), + Tag.String("facing") + ); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/IronChainBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/IronChainBlockHandler.java new file mode 100644 index 0000000..6adce11 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/IronChainBlockHandler.java @@ -0,0 +1,25 @@ +package net.theevilreaper.bounce.block.type; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; + +import java.util.Collection; +import java.util.List; + +public class IronChainBlockHandler implements BlockHandler { + + @Override + public Key getKey() { + return Block.IRON_CHAIN.key(); + } + + @Override + public Collection> getBlockEntityTags() { + return List.of( + Tag.String("axis"), + Tag.Boolean("waterlogged") + ); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/LecternBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/LecternBlockHandler.java new file mode 100644 index 0000000..7bfcdb2 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/LecternBlockHandler.java @@ -0,0 +1,26 @@ +package net.theevilreaper.bounce.block.type; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.List; + +public class LecternBlockHandler implements BlockHandler { + @Override + public Key getKey() { + return Block.LECTERN.key(); + } + + @Override + public Collection> getBlockEntityTags() { + return List.of( + Tag.String("facing"), + Tag.Boolean("has_book"), + Tag.Boolean("powered") + ); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/LeverBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/LeverBlockHandler.java new file mode 100644 index 0000000..537839e --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/LeverBlockHandler.java @@ -0,0 +1,25 @@ +package net.theevilreaper.bounce.block.type; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; + +import java.util.Collection; +import java.util.List; + +public class LeverBlockHandler implements BlockHandler { + @Override + public Key getKey() { + return Block.LEVER.key(); + } + + @Override + public Collection> getBlockEntityTags() { + return List.of( + Tag.String("face"), + Tag.String("facing"), + Tag.Boolean("powered") + ); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/SlabBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/SlabBlockHandler.java new file mode 100644 index 0000000..2f88cfe --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/SlabBlockHandler.java @@ -0,0 +1,30 @@ +package net.theevilreaper.bounce.block.type; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; + +import java.util.Collection; +import java.util.List; + +public class SlabBlockHandler implements BlockHandler { + + private final Key key; + + public SlabBlockHandler(Key key) { + this.key = key; + } + + @Override + public Key getKey() { + return this.key; + } + + @Override + public Collection> getBlockEntityTags() { + return List.of( + Tag.String("type"), + Tag.Boolean("waterlogged") + ); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/TorchBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/TorchBlockHandler.java new file mode 100644 index 0000000..49941b2 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/TorchBlockHandler.java @@ -0,0 +1,20 @@ +package net.theevilreaper.bounce.block.type; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; + +import java.util.Collection; +import java.util.List; + +public class TorchBlockHandler implements BlockHandler { + @Override + public Key getKey() { + return Key.key("minecraft:torch"); + } + + @Override + public Collection> getBlockEntityTags() { + return List.of(Tag.String("facing")); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/gates/GateBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/gates/GateBlockHandler.java new file mode 100644 index 0000000..d9245a1 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/gates/GateBlockHandler.java @@ -0,0 +1,32 @@ +package net.theevilreaper.bounce.block.type.gates; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; + +import java.util.Collection; +import java.util.List; + +public class GateBlockHandler implements BlockHandler { + + private final Key key; + + public GateBlockHandler(Key key) { + this.key = key; + } + + @Override + public Key getKey() { + return key; + } + + @Override + public Collection> getBlockEntityTags() { + return List.of( + Tag.String("facing"), + Tag.Boolean("in_wall"), + Tag.Boolean("open"), + Tag.Boolean("powered") + ); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/grates/IronGrateBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/grates/IronGrateBlockHandler.java new file mode 100644 index 0000000..68aebbc --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/grates/IronGrateBlockHandler.java @@ -0,0 +1,27 @@ +package net.theevilreaper.bounce.block.type.grates; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.item.Material; +import net.minestom.server.tag.Tag; + +import java.util.Collection; +import java.util.List; + +public class IronGrateBlockHandler implements BlockHandler { + @Override + public Key getKey() { + return Material.IRON_BARS.key(); + } + + @Override + public Collection> getBlockEntityTags() { + return List.of( + Tag.Boolean("east"), + Tag.Boolean("north"), + Tag.Boolean("south"), + Tag.Boolean("west"), + Tag.Boolean("waterlogged") + ); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/lantern/LanternBlockFactory.java b/block/src/main/java/net/theevilreaper/bounce/block/type/lantern/LanternBlockFactory.java new file mode 100644 index 0000000..a4d230f --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/lantern/LanternBlockFactory.java @@ -0,0 +1,44 @@ +package net.theevilreaper.bounce.block.type.lantern; + +import net.minestom.server.instance.block.Block; +import org.jetbrains.annotations.Contract; + +public interface LanternBlockFactory { + + /** + * Creates a new {@link LanternBlockHandler} for the specified block type. + * + * @param type the type of block to create a handler for + * @return a new {@link LanternBlockHandler} for the specified block type + */ + @Contract("_ -> new") + static LanternBlockHandler create(Type type) { + return new LanternBlockHandler(type.getBlock()); + } + + enum Type { + + LANTERN(Block.LANTERN), + SOUL_LANTERN(Block.SOUL_LANTERN); + + private final Block block; + + /** + * Constructs a new enumeration entry with the specified block. + * + * @param block the block associated with this type + */ + Type(Block block) { + this.block = block; + } + + /** + * Gets the block associated with this type. + * + * @return the block + */ + public Block getBlock() { + return this.block; + } + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/lantern/LanternBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/lantern/LanternBlockHandler.java new file mode 100644 index 0000000..dfc5813 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/lantern/LanternBlockHandler.java @@ -0,0 +1,49 @@ +package net.theevilreaper.bounce.block.type.lantern; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; + +import java.util.Collection; +import java.util.List; + +/** + * Represents the block handler for the lantern block. + * + * @author theEvilReaper + * @version 1.0.0 + * @since 0.1.0 + */ +public class LanternBlockHandler implements BlockHandler { + + private final Block block; + + /** + * Constructs a new {@code LanternBlockHandler} with the specified block. + * + * @param block the block associated with this handler + */ + LanternBlockHandler(Block block) { + this.block = block; + } + + /** + * {@inheritDoc} + */ + @Override + public Key getKey() { + return block.key(); + } + + /** + * {@inheritDoc} + */ + @Override + public Collection> getBlockEntityTags() { + return List.of( + Tag.Boolean("hanging"), + Tag.Boolean("waterlogged") + ); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/lantern/package-info.java b/block/src/main/java/net/theevilreaper/bounce/block/type/lantern/package-info.java new file mode 100644 index 0000000..e66a654 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/lantern/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.bounce.block.type.lantern; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/package-info.java b/block/src/main/java/net/theevilreaper/bounce/block/type/package-info.java new file mode 100644 index 0000000..6c80ca8 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.bounce.block.type; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/player/PlayerHeadBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/player/PlayerHeadBlockHandler.java new file mode 100644 index 0000000..e72899e --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/player/PlayerHeadBlockHandler.java @@ -0,0 +1,25 @@ +package net.theevilreaper.bounce.block.type.player; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; + +import java.util.Collection; +import java.util.List; + +public class PlayerHeadBlockHandler implements BlockHandler { + + @Override + public Key getKey() { + return Block.PLAYER_HEAD.key(); + } + + @Override + public Collection> getBlockEntityTags() { + return List.of( + Tag.Boolean("powered"), + Tag.Integer("rotation") + ); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/player/PlayerWallHeadBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/player/PlayerWallHeadBlockHandler.java new file mode 100644 index 0000000..3638c22 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/player/PlayerWallHeadBlockHandler.java @@ -0,0 +1,25 @@ +package net.theevilreaper.bounce.block.type.player; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; + +import java.util.Collection; +import java.util.List; + +public class PlayerWallHeadBlockHandler implements BlockHandler { + + @Override + public Key getKey() { + return Block.PLAYER_WALL_HEAD.key(); + } + + @Override + public Collection> getBlockEntityTags() { + return List.of( + Tag.String("facing"), + Tag.Boolean("powered") + ); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/player/package-info.java b/block/src/main/java/net/theevilreaper/bounce/block/type/player/package-info.java new file mode 100644 index 0000000..5a5a7ac --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/player/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.bounce.block.type.player; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/stair/StairBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/stair/StairBlockHandler.java new file mode 100644 index 0000000..161f8f6 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/stair/StairBlockHandler.java @@ -0,0 +1,34 @@ +package net.theevilreaper.bounce.block.type.stair; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.List; + +public class StairBlockHandler implements BlockHandler { + + private final Block block; + + public StairBlockHandler(@NotNull Block block) { + this.block = block; + } + + @Override + public @NotNull Key getKey() { + return block.key(); + } + + @Override + public @NotNull Collection> getBlockEntityTags() { + return List.of( + Tag.String("facing"), + Tag.String("half"), + Tag.String("shape"), + Tag.Boolean("waterlogged") + ); + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/stair/StairType.java b/block/src/main/java/net/theevilreaper/bounce/block/type/stair/StairType.java new file mode 100644 index 0000000..d632d63 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/stair/StairType.java @@ -0,0 +1,23 @@ +package net.theevilreaper.bounce.block.type.stair; + +import net.minestom.server.instance.block.Block; + +public enum StairType { + + OAK(Block.OAK_STAIRS), + SPRUCE(Block.SPRUCE_STAIRS), + BIRCH(Block.BIRCH_STAIRS), + JUNGLE(Block.JUNGLE_STAIRS), + ACACIA(Block.ACACIA_STAIRS), + DARK_OAK(Block.DARK_OAK_STAIRS); + + private final Block block; + + StairType(Block block) { + this.block = block; + } + + public Block getBlock() { + return block; + } +} diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/stair/package-info.java b/block/src/main/java/net/theevilreaper/bounce/block/type/stair/package-info.java new file mode 100644 index 0000000..79e7fbc --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/stair/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.bounce.block.type.stair; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/block/src/main/java/net/theevilreaper/bounce/block/type/stairs/StairsBlockHandler.java b/block/src/main/java/net/theevilreaper/bounce/block/type/stairs/StairsBlockHandler.java new file mode 100644 index 0000000..bed85c9 --- /dev/null +++ b/block/src/main/java/net/theevilreaper/bounce/block/type/stairs/StairsBlockHandler.java @@ -0,0 +1,33 @@ +package net.theevilreaper.bounce.block.type.stairs; + +import net.kyori.adventure.key.Key; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.tag.Tag; + +import java.util.Collection; +import java.util.List; + +public class StairsBlockHandler implements BlockHandler { + + private final Block block; + + public StairsBlockHandler(Block block) { + this.block = block; + } + + @Override + public Key getKey() { + return this.block.key(); + } + + @Override + public Collection> getBlockEntityTags() { + return List.of( + Tag.String("facing"), + Tag.String("half"), + Tag.String("shape"), + Tag.Boolean("waterlogged") + ); + } +} diff --git a/block/src/test/java/net/theevilreaper/bounce/block/type/lantern/LanternBlockFactoryTest.java b/block/src/test/java/net/theevilreaper/bounce/block/type/lantern/LanternBlockFactoryTest.java new file mode 100644 index 0000000..43dcb26 --- /dev/null +++ b/block/src/test/java/net/theevilreaper/bounce/block/type/lantern/LanternBlockFactoryTest.java @@ -0,0 +1,17 @@ +package net.theevilreaper.bounce.block.type.lantern; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +import static org.junit.jupiter.api.Assertions.*; + +class LanternBlockFactoryTest { + + @ParameterizedTest(name = "Test creation for lantern type {0}") + @EnumSource(LanternBlockFactory.Type.class) + void testLanternBlockHandlerCreation(LanternBlockFactory.Type type) { + LanternBlockHandler lanternBlockHandler = LanternBlockFactory.create(type); + assertNotNull(lanternBlockHandler, "LanternBlockHandler should not be null for type: " + type); + assertEquals(type.getBlock().key(), lanternBlockHandler.getKey()); + } +} diff --git a/build.gradle.kts b/build.gradle.kts index a72b375..53f7a60 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,6 +14,7 @@ dependencies { implementation(platform(libs.mycelium.bom)) implementation(platform(libs.aonyx.bom)) implementation(platform(libs.cloudnet.bom)) + implementation(project(":block")) implementation(libs.adventure) implementation(libs.pvp) implementation(libs.minestom) diff --git a/settings.gradle.kts b/settings.gradle.kts index 47f0345..c3dc737 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -69,4 +69,5 @@ dependencyResolutionManagement { } include("common") -include("setup") \ No newline at end of file +include("setup") +include("block") \ No newline at end of file diff --git a/setup/build.gradle.kts b/setup/build.gradle.kts index 8cab97c..849c17f 100644 --- a/setup/build.gradle.kts +++ b/setup/build.gradle.kts @@ -11,6 +11,7 @@ description = "Bounce Setup Server" dependencies { implementation(project(":common")) + implementation(project(":block")) implementation(platform(libs.mycelium.bom)) implementation(platform(libs.aonyx.bom)) implementation(libs.adventure) diff --git a/src/main/java/net/theevilreaper/bounce/Bounce.java b/src/main/java/net/theevilreaper/bounce/Bounce.java index 02bf24a..c040f9c 100644 --- a/src/main/java/net/theevilreaper/bounce/Bounce.java +++ b/src/main/java/net/theevilreaper/bounce/Bounce.java @@ -14,7 +14,13 @@ import net.minestom.server.event.player.PlayerChatEvent; import net.minestom.server.event.player.PlayerDisconnectEvent; import net.minestom.server.event.player.PlayerSpawnEvent; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; +import net.minestom.server.instance.block.BlockManager; import net.theevilreaper.aves.map.provider.MapProvider; +import net.theevilreaper.bounce.block.BlockLoader; +import net.theevilreaper.bounce.block.BlockLoaderBuilder; +import net.theevilreaper.bounce.block.type.lantern.LanternBlockFactory; import net.theevilreaper.bounce.commands.StartCommand; import net.theevilreaper.bounce.common.ListenerHandling; import net.theevilreaper.bounce.common.config.GameConfig; @@ -92,6 +98,7 @@ public void load() { .add(CombatFeatures.VANILLA_ENCHANTMENT) .build(); globalEventHandler.addChild(featureSet.createNode()); + loadBlocks(); } public void unload() { @@ -153,4 +160,21 @@ private void handleGeneralJoin(@NotNull Player player) { this.mapProvider.teleportToSpawn(player, false); this.scoreboard.addViewer(player); } + + private void loadBlocks() { + BlockManager blockHandler = MinecraftServer.getBlockManager(); + BlockLoader blockLoader = BlockLoader.builder(blockHandler); + blockLoader + .torch() + .candle() + .barrel() + .fenceGate() + .ironBars() + .grindStone() + .lanternVariant(LanternBlockFactory.Type.LANTERN) + .ironChain() + .stairs() + .slab() + .flowerPot(); + } }