Skip to content

Commit 77df214

Browse files
better multiblock API
1 parent df0831d commit 77df214

File tree

5 files changed

+185
-154
lines changed

5 files changed

+185
-154
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package com.rae.formicapi.multiblock;
2+
3+
import com.rae.crowns.CROWNS;
4+
import net.minecraft.core.BlockPos;
5+
import net.minecraft.core.Direction;
6+
import net.minecraft.core.Vec3i;
7+
import net.minecraft.world.level.BlockGetter;
8+
import net.minecraft.world.level.Level;
9+
import net.minecraft.world.level.block.DirectionalBlock;
10+
import net.minecraft.world.level.block.state.BlockState;
11+
import net.minecraft.world.phys.shapes.CollisionContext;
12+
import net.minecraft.world.phys.shapes.VoxelShape;
13+
14+
import java.util.ArrayDeque;
15+
import java.util.HashSet;
16+
import java.util.Queue;
17+
import java.util.Set;
18+
19+
public interface IMBController {
20+
Vec3i getDefaultOffset();
21+
Vec3i getDefaultSize();
22+
VoxelShape getGlobalShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context);
23+
MBStructureBlock getStructure();
24+
default Vec3i getOffset(Direction facing, boolean mirrorOnDir){
25+
final int dirMultiply = facing.getAxisDirection() == Direction.AxisDirection.NEGATIVE && mirrorOnDir ? -1 : 1;
26+
Vec3i defaultOffset = getDefaultOffset();
27+
return switch (facing.getAxis()){
28+
case Z -> new Vec3i( defaultOffset.getZ(), defaultOffset.getY(), dirMultiply *defaultOffset.getX());
29+
case Y -> new Vec3i( defaultOffset.getY(), dirMultiply *defaultOffset.getX(),defaultOffset.getZ());
30+
default -> new Vec3i( dirMultiply *defaultOffset.getX(),defaultOffset.getY(), defaultOffset.getZ());
31+
};
32+
}
33+
34+
default Vec3i getSize(Direction facing){
35+
Vec3i defaultSize = getDefaultSize();
36+
return switch (facing.getAxis()){
37+
case Z -> new Vec3i(defaultSize.getZ(), defaultSize.getY(), defaultSize.getX());
38+
case Y -> new Vec3i(defaultSize.getY(), defaultSize.getX(),defaultSize.getZ());
39+
default -> defaultSize;
40+
};
41+
}
42+
43+
44+
default void repairStructure(Level level, BlockPos controlPos, Direction facing) {
45+
if (level.isClientSide()) return;
46+
MBStructureBlock structure = getStructure();
47+
Set<BlockPos> visited = new HashSet<>();
48+
Queue<Node> toVisit = new ArrayDeque<>();
49+
50+
Vec3i off = getOffset(facing, false);
51+
Vec3i size = getSize(facing);
52+
BlockPos minCorner = controlPos.offset(off);
53+
54+
for (Direction dir : Direction.values()) {
55+
BlockPos neighborPos = controlPos.relative(dir);
56+
57+
if (isInsideBounds(neighborPos, minCorner, size)) {
58+
toVisit.add(new Node(dir, neighborPos));
59+
}
60+
}
61+
int i = 0;
62+
while (!toVisit.isEmpty()) {
63+
Node node = toVisit.poll();
64+
BlockState current = level.getBlockState(node.pos);
65+
66+
67+
if (!current.is(structure)) {
68+
level.setBlockAndUpdate(node.pos, structure.defaultBlockState().setValue(DirectionalBlock.FACING, node.fromDir.getOpposite()));
69+
visited.add(node.pos);
70+
71+
for (Direction dir : Direction.values()) {
72+
BlockPos neighborPos = node.pos.relative(dir);
73+
//System.out.println(neighborPos);
74+
75+
if (isInsideBounds(neighborPos, minCorner, size) && !neighborPos.equals(controlPos) && !visited.contains(neighborPos)) {
76+
toVisit.add(new Node(dir, neighborPos));
77+
}
78+
}
79+
}
80+
i++;
81+
if (i > 100) {
82+
CROWNS.LOGGER.warn("More than 100 blocks");
83+
break;
84+
}
85+
}
86+
}
87+
88+
default boolean isInsideBounds(BlockPos pos, BlockPos minCorner, Vec3i size) {
89+
int dx = minCorner.getX() - pos.getX();
90+
int dy = minCorner.getY() - pos.getY() ;
91+
int dz = minCorner.getZ() - pos.getZ();
92+
return dx >= 0 && dx < size.getX() &&
93+
dy >= 0 && dy < size.getY() &&
94+
dz >= 0 && dz < size.getZ();
95+
}
96+
record Node(Direction fromDir, BlockPos pos){
97+
}
98+
}

src/main/java/com/rae/formicapi/multiblock/MBController.java

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import net.minecraft.core.BlockPos;
44
import net.minecraft.core.Direction;
5-
import net.minecraft.core.Vec3i;
65
import net.minecraft.world.entity.LivingEntity;
76
import net.minecraft.world.item.ItemStack;
87
import net.minecraft.world.item.context.BlockPlaceContext;
@@ -20,19 +19,17 @@
2019
* the main block for the multiblock, this the block that is used for the model, to make the model work you will need
2120
* to look at the default offset given in the MBShape for the size chosen
2221
*/
23-
public abstract class MBController extends DirectionalBlock {
24-
protected final MBShape shape;
25-
final DirectionalBlock structure;
26-
protected MBController(Properties properties, DirectionalBlock structure) {
22+
public abstract class MBController extends DirectionalBlock implements IMBController {
23+
final MBStructureBlock structure;
24+
protected MBController(Properties properties, MBStructureBlock structure) {
2725
super(properties);
2826
this.structure = structure;
29-
this.shape = makeShapes(structure);
3027
this.registerDefaultState(this.defaultBlockState().setValue(FACING, Direction.NORTH));
3128
}
3229
@Override
3330
public void setPlacedBy(@NotNull Level worldIn, @NotNull BlockPos pos, @NotNull BlockState state, @Nullable LivingEntity entity, @NotNull ItemStack stack) {
3431
super.setPlacedBy(worldIn, pos, state, entity, stack);
35-
shape.repairStructure(worldIn, pos, state.getValue(FACING));
32+
repairStructure(worldIn, pos, state.getValue(FACING));
3633
}
3734
public BlockState getStateForPlacement(@NotNull BlockPlaceContext context) {
3835
return Objects.requireNonNull(super.getStateForPlacement(context)).setValue(FACING,context.getClickedFace());
@@ -43,15 +40,10 @@ protected void createBlockStateDefinition(StateDefinition.@NotNull Builder<Block
4340
super.createBlockStateDefinition(builder);
4441
builder.add(FACING);
4542
}
46-
protected abstract MBShape makeShapes(DirectionalBlock structure);
47-
48-
public DirectionalBlock getStructure() {
43+
@Override
44+
public MBStructureBlock getStructure() {
4945
return structure;
5046
}
51-
public Vec3i getPlaceOffset(Direction facing) {
52-
return shape.getOffset(facing,true);
53-
}
54-
public Vec3i getSize(Direction facing){
55-
return shape.getSize(facing);
56-
}
47+
48+
5749
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.rae.formicapi.multiblock;
2+
3+
import com.simibubi.create.content.kinetics.base.DirectionalKineticBlock;
4+
import net.minecraft.core.BlockPos;
5+
import net.minecraft.core.Direction;
6+
import net.minecraft.world.entity.LivingEntity;
7+
import net.minecraft.world.item.ItemStack;
8+
import net.minecraft.world.item.context.BlockPlaceContext;
9+
import net.minecraft.world.level.Level;
10+
import net.minecraft.world.level.block.state.BlockState;
11+
import org.jetbrains.annotations.NotNull;
12+
import org.jetbrains.annotations.Nullable;
13+
14+
import java.util.Objects;
15+
16+
/**
17+
* the main block for the multiblock, this the block that is used for the model, to make the model work you will need
18+
* to look at the default offset given in the MBShape for the size chosen
19+
*/
20+
public abstract class MBKineticController extends DirectionalKineticBlock implements IMBController {
21+
final MBStructureBlock structure;
22+
protected MBKineticController(Properties properties, MBStructureBlock structure) {
23+
super(properties);
24+
this.structure = structure;
25+
this.registerDefaultState(this.defaultBlockState().setValue(FACING, Direction.NORTH));
26+
}
27+
@Override
28+
public void setPlacedBy(@NotNull Level worldIn, @NotNull BlockPos pos, @NotNull BlockState state, @Nullable LivingEntity entity, @NotNull ItemStack stack) {
29+
super.setPlacedBy(worldIn, pos, state, entity, stack);
30+
repairStructure(worldIn, pos, state.getValue(FACING));
31+
}
32+
public BlockState getStateForPlacement(@NotNull BlockPlaceContext context) {
33+
return Objects.requireNonNull(super.getStateForPlacement(context)).setValue(FACING,context.getClickedFace());
34+
35+
}
36+
37+
public MBStructureBlock getStructure() {
38+
return structure;
39+
}
40+
}

src/main/java/com/rae/formicapi/multiblock/MBShape.java

Lines changed: 0 additions & 114 deletions
This file was deleted.

0 commit comments

Comments
 (0)