|
| 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 | +} |
0 commit comments