Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions block/README.md
Original file line number Diff line number Diff line change
@@ -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.
34 changes: 34 additions & 0 deletions block/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -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")
}
}
}
Original file line number Diff line number Diff line change
@@ -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();
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@NotNullByDefault
package net.theevilreaper.bounce.block;

import org.jetbrains.annotations.NotNullByDefault;
Original file line number Diff line number Diff line change
@@ -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<Tag<?>> getBlockEntityTags() {
return List.of(
Tag.Integer("rotating")
);
}
}
Original file line number Diff line number Diff line change
@@ -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<Tag<?>> getBlockEntityTags() {
return List.of(
Tag.String("facing"),
Tag.Boolean("open")
);
}
}
Original file line number Diff line number Diff line change
@@ -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<Tag<?>> getBlockEntityTags() {
return List.of(
Tag.Integer("candles"),
Tag.Boolean("lit"),
Tag.Boolean("waterlogged")
);
}
}
Original file line number Diff line number Diff line change
@@ -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<Tag<?>> getBlockEntityTags() {
return List.of(
Tag.String("face"),
Tag.String("facing")
);
}
}
Loading