Registering Materials
Time and Place of Registration
The registration is pretty similar to the item registration. Create
the block assets
and create a Blocks
singleton object that contains all BlockNovaMaterials
of your addon. All materials need to be
registered when Addon#init
is called, materials registered later won't work properly. Similar to the Items
singleton
object, your singleton object might then look like this:
Now add the init call to your main class:
Again, calling the init function will cause the class and all its fields to be loaded.
BlockOptions
Before registering a new Block, you need to create a BlockOptions
instance. This class contains properties for
breaking/placing custom blocks. Let's create an instance that can be broken with a stone pickaxe:
private val STONE = BlockOptions(
3.0, // (1)!
listOf(ToolCategory.PICKAXE), // (2)!
ToolTier.STONE, // (3)!
true, // (4)!
SoundGroup.STONE, // (5)!
Material.NETHERITE_BLOCK, // (6)!
true // (7)!
)
- This is the hardness of the block. It determines how long it takes to break the block. This value currently doesn't affect explosions.
- A list of tool categories that are suitable to break this block. Can be empty.
- The minimum
ToolTier
that is required to properly break this block (Like diamond for obsidian). Can be null. - Whether a tool is required to receive drops.
- The sound group to use for this block. Sound groups include sounds for hitting, breaking and placing a block as well as stepping and falling on a block. You can also create your own sound group with your own custom sounds.
- The break particles that spawn when the block is broken. This is only relevant for armor stand based blocks, but since you can't know if your block will end up being and armor stand block, you'll always have to set this value.
- Whether a break animation should be displayed while breaking the block.
Registering the block
Using the options specified above, you can now register your block material via the builders obtained by calling
NovaMaterialRegistry#block
or NovaMaterialRegistry#tileEntity
. Unlike item materials, block- and tile-entity materials
can only be registered using the builder functions.
// normal block
val MY_BLOCK = NovaMaterialRegistry.block(ExampleAddon, "example_block").blockOptions(STONE).register()
// normal directional block (North, East, South, West)
val MY_BLOCK_1 = NovaMaterialRegistry.block(ExampleAddon, "example_block").blockOptions(STONE).properties(Directional.NORMAL).register()
// normal directional block (North, East, South, West, Up, Down)
val MY_BLOCK_2 = NovaMaterialRegistry.block(ExampleAddon, "example_block").blockOptions(STONE).properties(Directional.ALL).register()
// directional tile entity block (North, East, South, West)
val MY_TILE_ENTITY_1 = NovaMaterialRegistry.tileEntity(ExampleAddon, "example_block", ::ExampleTileEntity).blockOptions(STONE).properties(Directional.NORMAL).register()
Don't forget to call register()
at the end of the builder chain.
Tip
The examples above are far from everything you can do, as it is also possible to set a custom NovaBlock
,
NovaItem
, PlaceCheckFun
or MultiBlockLoader
.
Additional properties
NovaBlock
The NovaBlock
handles the logic of all blocks of that material (or multiple materials, if the same NovaBlock
is
registered to them). This logic includes handling interacts, returning drops, playing the break sound, showing break
particles and more. Depending on if you register a TileEntity or a normal block, the TileEntityBlock
or
NovaBlock$Default
is used.
Info
NovaBlock
is very similar to NovaItem
in concept, with the exception of it being for blocks and it's ability
to be used in multiple materials.
Block properties
Block properties store data stored inside the NovaBlockState
.
Currently, the only block property available is Directional
, but addons can create custom block properties.
Block properties can be accessed by calling the getProperty(BlockPropertyType)
or getProperty(KClass)
methods in
NovaBlockState
.
MultiBlockLoader
The MultiBlockLoader
is a typealias for (BlockPos) -> List<BlockPos>
which is just supposed to return a list of
block positions that are also part of this block. This list should not include the position of the base block.
PlaceCheckFun
The PlaceCheckFun
is a typealias for ((Player, ItemStack, Location) -> CompletableFuture<Boolean>)
used to check
for placement permissions of multi blocks.