+ fan_block

+ redstone_powered_fan_block
This commit is contained in:
Glitchlabs
2026-08-04 16:06:43 +02:00
parent 48a1ecf7e4
commit 15a251ed9c
18 changed files with 166 additions and 18 deletions
+1 -1
View File
@@ -27,7 +27,7 @@ mod_name=Ornamentum
## The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. ## The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=All Rights Reserved mod_license=All Rights Reserved
# The mod version. See https://semver.org/ # The mod version. See https://semver.org/
mod_version=1.3.0 mod_version=1.4.0
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources. # This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html # See https://maven.apache.org/guides/mini/guide-naming-conventions.html
@@ -1,4 +1,4 @@
// 1.21.1 2026-08-04T15:40:22.174290355 Tags for minecraft:block mod id ornamentum // 1.21.1 2026-08-04T16:04:14.852760951 Tags for minecraft:block mod id ornamentum
585e131e594c65c425b3e81803fae3fdd63e2f03 data/c/tags/block/concretes.json 585e131e594c65c425b3e81803fae3fdd63e2f03 data/c/tags/block/concretes.json
354a0712e83c8365d9054ffc2a122cf7dd69ad53 data/c/tags/block/dyed.json 354a0712e83c8365d9054ffc2a122cf7dd69ad53 data/c/tags/block/dyed.json
8281ec180c87b02f17e4be444a350685b52f1e31 data/c/tags/block/dyed/black.json 8281ec180c87b02f17e4be444a350685b52f1e31 data/c/tags/block/dyed/black.json
@@ -31,10 +31,10 @@ ae7d2e386f2eb4df7cd8f8f3e0a4040cae7a13bf data/minecraft/tags/block/incorrect_for
5bf3d2f5afa06168fa3bb8de07bdbaff4f7980db data/minecraft/tags/block/incorrect_for_stone_tool.json 5bf3d2f5afa06168fa3bb8de07bdbaff4f7980db data/minecraft/tags/block/incorrect_for_stone_tool.json
ae7d2e386f2eb4df7cd8f8f3e0a4040cae7a13bf data/minecraft/tags/block/incorrect_for_wooden_tool.json ae7d2e386f2eb4df7cd8f8f3e0a4040cae7a13bf data/minecraft/tags/block/incorrect_for_wooden_tool.json
26a948fa0b92ea3e254ed5b6aa26e1ab478e0715 data/minecraft/tags/block/mineable/axe.json 26a948fa0b92ea3e254ed5b6aa26e1ab478e0715 data/minecraft/tags/block/mineable/axe.json
d069cc13cfb3d900d448089fa1423891be6b25a7 data/minecraft/tags/block/mineable/pickaxe.json fbbc0d0870ebfa49c503bf457142a372c8a9efd1 data/minecraft/tags/block/mineable/pickaxe.json
ec379d82d3fd4ddd3a9f6664ddb9aaaf0290834d data/minecraft/tags/block/needs_diamond_tool.json ec379d82d3fd4ddd3a9f6664ddb9aaaf0290834d data/minecraft/tags/block/needs_diamond_tool.json
bad82b905081d37caba6026145cd8611bd369d5c data/minecraft/tags/block/needs_iron_tool.json bad82b905081d37caba6026145cd8611bd369d5c data/minecraft/tags/block/needs_iron_tool.json
20f898296b7e69ff74393d2b1d7e15dbfae5e8b5 data/minecraft/tags/block/needs_stone_tool.json 66f17565eae49456c2f69d2fbedb9ac92ef1c90e data/minecraft/tags/block/needs_stone_tool.json
8b771a730def8958b41eb9c4e3b6628365c5d429 data/minecraft/tags/block/occludes_vibration_signals.json 8b771a730def8958b41eb9c4e3b6628365c5d429 data/minecraft/tags/block/occludes_vibration_signals.json
aad2571fcde7dc73bb943c24237eb17699067cfb data/minecraft/tags/block/sculk_replaceable.json aad2571fcde7dc73bb943c24237eb17699067cfb data/minecraft/tags/block/sculk_replaceable.json
6014324ec06e8974ac7b92e7c0724c7710a6331c data/minecraft/tags/block/sculk_replaceable_world_gen.json 6014324ec06e8974ac7b92e7c0724c7710a6331c data/minecraft/tags/block/sculk_replaceable_world_gen.json
@@ -1,4 +1,4 @@
// 1.21.1 2026-08-04T15:40:22.170254506 Loot Tables // 1.21.1 2026-08-04T16:04:14.84763909 Loot Tables
b840d3c223a8269ea4ead11f9d1a337f16c87728 data/ornamentum/loot_table/blocks/agender_flag.json b840d3c223a8269ea4ead11f9d1a337f16c87728 data/ornamentum/loot_table/blocks/agender_flag.json
c5c3cbbff0b4af321ae05896dbd68e551f598c86 data/ornamentum/loot_table/blocks/amethyst_grate.json c5c3cbbff0b4af321ae05896dbd68e551f598c86 data/ornamentum/loot_table/blocks/amethyst_grate.json
f44341b5b821a1ea423b1f9e81a020e324a3952e data/ornamentum/loot_table/blocks/ametist_bricks.json f44341b5b821a1ea423b1f9e81a020e324a3952e data/ornamentum/loot_table/blocks/ametist_bricks.json
@@ -253,6 +253,7 @@ c8ed783c578945eba756818d8115020a3ab779ce data/ornamentum/loot_table/blocks/red_g
a3838e224bc3635d7edc30d40f91c29acc6dc855 data/ornamentum/loot_table/blocks/red_pattern_block_stairs.json a3838e224bc3635d7edc30d40f91c29acc6dc855 data/ornamentum/loot_table/blocks/red_pattern_block_stairs.json
f477ebd0e0fe21e7be3e81bf4aa99a794773eb9b data/ornamentum/loot_table/blocks/red_wool_slab.json f477ebd0e0fe21e7be3e81bf4aa99a794773eb9b data/ornamentum/loot_table/blocks/red_wool_slab.json
46cbc6cb332d5a9f3665d87af3d6b1b8a32c6836 data/ornamentum/loot_table/blocks/red_wool_stairs.json 46cbc6cb332d5a9f3665d87af3d6b1b8a32c6836 data/ornamentum/loot_table/blocks/red_wool_stairs.json
a915187cc084eada3434a9d5a3b897a453cfb32b data/ornamentum/loot_table/blocks/redstone_powered_fan_block.json
1507f4311dcc09e0f57838231d41b03901f4aeb6 data/ornamentum/loot_table/blocks/smooth_basalt_bricks.json 1507f4311dcc09e0f57838231d41b03901f4aeb6 data/ornamentum/loot_table/blocks/smooth_basalt_bricks.json
2cbe0836062a04955c5b0e14b3e0e7d5d5d0e3d4 data/ornamentum/loot_table/blocks/smooth_basalt_bricks_slab.json 2cbe0836062a04955c5b0e14b3e0e7d5d5d0e3d4 data/ornamentum/loot_table/blocks/smooth_basalt_bricks_slab.json
70acce0530e54306728421b99736d889bb563a52 data/ornamentum/loot_table/blocks/smooth_basalt_bricks_stairs.json 70acce0530e54306728421b99736d889bb563a52 data/ornamentum/loot_table/blocks/smooth_basalt_bricks_stairs.json
@@ -1,2 +1,2 @@
// 1.21.1 2026-08-04T15:40:22.173401134 Languages: en_us for mod: ornamentum // 1.21.1 2026-08-04T16:04:14.851766142 Languages: en_us for mod: ornamentum
62aa32c03952421205e9465fffaf8a6f551b9fd9 assets/ornamentum/lang/en_us.json 90a337aff5d6d319f41ac424b31c282a95e30b9f assets/ornamentum/lang/en_us.json
@@ -253,6 +253,7 @@
"block.ornamentum.red_pattern_block_stairs": "Red Pattern Block Stairs", "block.ornamentum.red_pattern_block_stairs": "Red Pattern Block Stairs",
"block.ornamentum.red_wool_slab": "Red Wool Slab", "block.ornamentum.red_wool_slab": "Red Wool Slab",
"block.ornamentum.red_wool_stairs": "Red Wool Stairs", "block.ornamentum.red_wool_stairs": "Red Wool Stairs",
"block.ornamentum.redstone_powered_fan_block": "Redstone Powered Fan Block",
"block.ornamentum.smooth_basalt_bricks": "Purpur Bricks", "block.ornamentum.smooth_basalt_bricks": "Purpur Bricks",
"block.ornamentum.smooth_basalt_bricks_slab": "Purpur Bricks Slab", "block.ornamentum.smooth_basalt_bricks_slab": "Purpur Bricks Slab",
"block.ornamentum.smooth_basalt_bricks_stairs": "Purpur Bricks Stairs", "block.ornamentum.smooth_basalt_bricks_stairs": "Purpur Bricks Stairs",
@@ -1,6 +1,7 @@
{ {
"values": [ "values": [
"ornamentum:fan_block", "ornamentum:fan_block",
"ornamentum:redstone_powered_fan_block",
"ornamentum:link_block", "ornamentum:link_block",
"ornamentum:iron_shelf", "ornamentum:iron_shelf",
"ornamentum:red_pattern_block", "ornamentum:red_pattern_block",
@@ -3,6 +3,7 @@
"ornamentum:iron_shelf", "ornamentum:iron_shelf",
"ornamentum:iron_grate", "ornamentum:iron_grate",
"ornamentum:link_block", "ornamentum:link_block",
"ornamentum:fan_block" "ornamentum:fan_block",
"ornamentum:redstone_powered_fan_block"
] ]
} }
@@ -0,0 +1,21 @@
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
],
"entries": [
{
"type": "minecraft:item",
"name": "ornamentum:redstone_powered_fan_block"
}
],
"rolls": 1.0
}
],
"random_sequence": "ornamentum:blocks/redstone_powered_fan_block"
}
@@ -17,6 +17,9 @@ public class ModBlocks {
public static final DeferredRegister.Blocks BLOCKS = public static final DeferredRegister.Blocks BLOCKS =
DeferredRegister.createBlocks(Ornamentum.MODID); DeferredRegister.createBlocks(Ornamentum.MODID);
public static final DeferredBlock<Block> REDSTONE_POWERED_FAN_BLOCK = registerBlock("redstone_powered_fan_block",
() -> new RedstonePowerdFanBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.IRON_BLOCK).noOcclusion()));
public static final DeferredBlock<Block> FAN_BLOCK = registerBlock("fan_block", public static final DeferredBlock<Block> FAN_BLOCK = registerBlock("fan_block",
() -> new FanBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.IRON_BLOCK).noOcclusion())); () -> new FanBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.IRON_BLOCK).noOcclusion()));
@@ -16,16 +16,10 @@ import java.util.Deque;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
/**
* A block that can be toggled on/off via shift-right-click.
* Toggling propagates through directly adjacent FanBlocks (BFS / flood-fill),
* similar to how a redstone wire network shares state.
*/
public class FanBlock extends Block { public class FanBlock extends Block {
public static final BooleanProperty ON = BooleanProperty.create("on"); public static final BooleanProperty ON = BooleanProperty.create("on");
// Safety cap so an absurdly large network can't cause a huge single-tick update.
private static final int MAX_NETWORK_SIZE = 4096; private static final int MAX_NETWORK_SIZE = 4096;
public FanBlock(Properties properties) { public FanBlock(Properties properties) {
@@ -49,10 +43,6 @@ public class FanBlock extends Block {
return InteractionResult.PASS; return InteractionResult.PASS;
} }
/**
* Flood-fills outward from {@code origin} through orthogonally adjacent FanBlocks
* and sets all of them to {@code newState}.
*/
private void toggleNetwork(Level level, BlockPos origin, boolean newState) { private void toggleNetwork(Level level, BlockPos origin, boolean newState) {
Set<BlockPos> visited = new HashSet<>(); Set<BlockPos> visited = new HashSet<>();
Deque<BlockPos> queue = new ArrayDeque<>(); Deque<BlockPos> queue = new ArrayDeque<>();
@@ -0,0 +1,86 @@
package ovh.glitchlabs.ornamentum.blocks.custom;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import javax.annotation.Nullable;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashSet;
import java.util.Set;
public class RedstonePowerdFanBlock extends Block {
public static final BooleanProperty ON = BooleanProperty.create("on");
private static final int MAX_NETWORK_SIZE = 4096;
public RedstonePowerdFanBlock(Properties properties) {
super(properties);
this.registerDefaultState(this.stateDefinition.any().setValue(ON, false));
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(ON);
}
@Override
protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) {
if (!oldState.is(state.getBlock()) && !level.isClientSide) {
boolean powered = level.hasNeighborSignal(pos);
if (powered != state.getValue(ON)) {
toggleNetwork(level, pos, powered);
}
}
}
@Override
protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block block, @Nullable BlockPos fromPos, boolean isMoving) {
if (!level.isClientSide) {
boolean powered = level.hasNeighborSignal(pos);
if (powered != state.getValue(ON)) {
toggleNetwork(level, pos, powered);
}
}
}
private void toggleNetwork(Level level, BlockPos origin, boolean newState) {
Set<BlockPos> visited = new HashSet<>();
Deque<BlockPos> queue = new ArrayDeque<>();
visited.add(origin.immutable());
queue.add(origin);
while (!queue.isEmpty() && visited.size() <= MAX_NETWORK_SIZE) {
BlockPos pos = queue.poll();
BlockState state = level.getBlockState(pos);
if (!(state.getBlock() instanceof RedstonePowerdFanBlock)) {
continue;
}
if (state.getValue(ON) != newState) {
level.setBlock(pos, state.setValue(ON, newState), Block.UPDATE_ALL);
}
for (Direction direction : Direction.values()) {
BlockPos neighborPos = pos.relative(direction);
if (visited.contains(neighborPos)) {
continue;
}
BlockState neighborState = level.getBlockState(neighborPos);
if (neighborState.getBlock() instanceof RedstonePowerdFanBlock) {
visited.add(neighborPos.immutable());
queue.add(neighborPos);
}
}
}
}
}
@@ -19,6 +19,7 @@ public class ModBlockLootTableProvider extends BlockLootSubProvider {
dropSelf(ModBlocks.DUCK.get()); dropSelf(ModBlocks.DUCK.get());
dropSelf(ModBlocks.FAN_BLOCK.get()); dropSelf(ModBlocks.FAN_BLOCK.get());
dropSelf(ModBlocks.REDSTONE_POWERED_FAN_BLOCK.get());
dropSelf(ModBlocks.BABY_TURTLE.get()); dropSelf(ModBlocks.BABY_TURTLE.get());
dropSelf(ModBlocks.LINK_BLOCK.get()); dropSelf(ModBlocks.LINK_BLOCK.get());
dropSelf(ModBlocks.IRON_SHELF.get()); dropSelf(ModBlocks.IRON_SHELF.get());
@@ -91,6 +91,7 @@ public class ModBlockTagProvider extends BlockTagsProvider {
tag(BlockTags.MINEABLE_WITH_PICKAXE) tag(BlockTags.MINEABLE_WITH_PICKAXE)
.add(ModBlocks.FAN_BLOCK.get()) .add(ModBlocks.FAN_BLOCK.get())
.add(ModBlocks.REDSTONE_POWERED_FAN_BLOCK.get())
.add(ModBlocks.LINK_BLOCK.get()) .add(ModBlocks.LINK_BLOCK.get())
.add(ModBlocks.IRON_SHELF.get()) .add(ModBlocks.IRON_SHELF.get())
@@ -406,6 +407,7 @@ public class ModBlockTagProvider extends BlockTagsProvider {
.add(ModBlocks.IRON_GRATE.get()) .add(ModBlocks.IRON_GRATE.get())
.add(ModBlocks.LINK_BLOCK.get()) .add(ModBlocks.LINK_BLOCK.get())
.add(ModBlocks.FAN_BLOCK.get()) .add(ModBlocks.FAN_BLOCK.get())
.add(ModBlocks.REDSTONE_POWERED_FAN_BLOCK.get())
; ;
tag(BlockTags.INCORRECT_FOR_GOLD_TOOL) tag(BlockTags.INCORRECT_FOR_GOLD_TOOL)
@@ -343,6 +343,7 @@ public class ModLanguageProvider extends LanguageProvider {
add(ModBlocks.LINK_BLOCK.get(), "Link Block"); add(ModBlocks.LINK_BLOCK.get(), "Link Block");
add(ModBlocks.FAN_BLOCK.get(), "Fan Block"); add(ModBlocks.FAN_BLOCK.get(), "Fan Block");
add(ModBlocks.REDSTONE_POWERED_FAN_BLOCK.get(), "Redstone Powered Fan Block");
add(ModBlocks.IRON_SHELF.get(), "Iron Shelf"); add(ModBlocks.IRON_SHELF.get(), "Iron Shelf");
add(ModBlocks.DUCK.get(), "Duck"); add(ModBlocks.DUCK.get(), "Duck");
@@ -0,0 +1,10 @@
{
"variants": {
"on=false": {
"model": "ornamentum:block/fan_block"
},
"on=true": {
"model": "ornamentum:block/fan_block_on"
}
}
}
@@ -0,0 +1,3 @@
{
"parent": "ornamentum:block/fan_block_on"
}
@@ -0,0 +1,11 @@
{
"type": "minecraft:stonecutting",
"group": "Ornamentum",
"ingredient": {
"item": "minecraft:iron_block"
},
"result": {
"count": 1,
"id": "ornamentum:fan_block"
}
}
@@ -0,0 +1,16 @@
{
"type": "minecraft:crafting_shapeless",
"category": "building",
"ingredients": [
{
"item": "ornamentum:fan_block"
},
{
"item": "ornamentum:fan_block"
}
],
"result": {
"count": 1,
"id": "ornamentum:redstone_powered_fan_block"
}
}