Junix03

Cable.java

Jan 20th, 2022
45
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.51 KB | None | 0 0
  1. package com.junix.logicboard.blocks;
  2.  
  3. import com.google.common.collect.ImmutableMap;
  4. import com.google.common.collect.Maps;
  5. import com.google.common.collect.Sets;
  6. import com.junix.logicboard.setup.Component;
  7. import com.junix.logicboard.setup.Registration;
  8. import net.minecraft.core.BlockPos;
  9. import net.minecraft.core.Direction;
  10. import net.minecraft.world.item.context.BlockPlaceContext;
  11. import net.minecraft.world.level.BlockGetter;
  12. import net.minecraft.world.level.Level;
  13. import net.minecraft.world.level.block.Block;
  14. import net.minecraft.world.level.block.state.BlockState;
  15. import net.minecraft.world.level.block.state.StateDefinition;
  16. import net.minecraft.world.level.block.state.properties.BlockStateProperties;
  17. import net.minecraft.world.level.block.state.properties.BooleanProperty;
  18. import net.minecraft.world.level.block.state.properties.IntegerProperty;
  19. import net.minecraft.world.phys.shapes.CollisionContext;
  20. import net.minecraft.world.phys.shapes.Shapes;
  21. import net.minecraft.world.phys.shapes.VoxelShape;
  22. import org.jetbrains.annotations.NotNull;
  23. import org.jetbrains.annotations.Nullable;
  24.  
  25. import java.util.Map;
  26. import java.util.Set;
  27.  
  28. public class Cable extends Component {
  29.  
  30. /* Properties */
  31. public static final BooleanProperty NORTH = BooleanProperty.create("north");
  32. public static final BooleanProperty EAST = BooleanProperty.create("east");
  33. public static final BooleanProperty SOUTH = BooleanProperty.create("south");
  34. public static final BooleanProperty WEST = BooleanProperty.create("west");
  35. public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
  36. public static final IntegerProperty SOURCE_DISTANCE = IntegerProperty.create("source_distance", 0, 4096);
  37.  
  38. /* VoxelShapes */
  39. private static final VoxelShape SHAPE_DOT = Block.box(5, 0, 5, 11, 1, 11);
  40. private static final VoxelShape SHAPE_N = Block.box(7, 0, 0, 9, 1, 5);
  41. private static final VoxelShape SHAPE_S = Block.box(7, 0, 11, 9, 1, 16);
  42. private static final VoxelShape SHAPE_W = Block.box(0, 0, 7, 5, 1, 9);
  43. private static final VoxelShape SHAPE_E = Block.box(11, 0, 7, 16, 1, 9);
  44.  
  45. /* Maps */
  46. public static final Map<Direction, BooleanProperty> PROPERTY_BY_DIRECTION = Maps.newEnumMap(ImmutableMap.of(Direction.NORTH, NORTH, Direction.EAST, EAST, Direction.SOUTH, SOUTH, Direction.WEST, WEST));
  47. private static final Map<Direction, VoxelShape> SHAPE_BY_DIRECTION = Maps.newEnumMap(ImmutableMap.of(Direction.NORTH, SHAPE_N, Direction.SOUTH, SHAPE_S, Direction.WEST, SHAPE_W, Direction.EAST, SHAPE_E));
  48. private static final Map<BlockState, VoxelShape> SHAPES_CACHE = Maps.newHashMap();
  49.  
  50. /* BlockStates */
  51. private final BlockState CROSS_STATE;
  52.  
  53. public Cable() {
  54. super(Registration.CABLE_BLOCK_PROPERTIES);
  55.  
  56. registerDefaultState(this.getStateDefinition().any()
  57. .setValue(NORTH, Boolean.FALSE)
  58. .setValue(SOUTH, Boolean.FALSE)
  59. .setValue(WEST, Boolean.FALSE)
  60. .setValue(EAST, Boolean.FALSE)
  61. .setValue(POWERED, Boolean.FALSE)
  62. .setValue(SOURCE_DISTANCE, 0));
  63.  
  64. BlockState crossState = defaultBlockState();
  65. for (Direction direction: Direction.Plane.HORIZONTAL)
  66. crossState.setValue(PROPERTY_BY_DIRECTION.get(direction), Boolean.TRUE);
  67. CROSS_STATE = crossState;
  68.  
  69. for (int north = 0; north < 2; north++)
  70. for (int south = 0; south < 2; south++)
  71. for (int west = 0; west < 2; west++)
  72. for (int east = 0; east < 2; east++) {
  73. System.out.println(north + " " + south + " " + west + " " + east);
  74. BlockState blockState = defaultBlockState();
  75. blockState.setValue(NORTH, north == 0).setValue(SOUTH, south == 0).setValue(WEST, west == 0).setValue(EAST, east == 0);
  76. SHAPES_CACHE.put(blockState, calculateShape(blockState));
  77. }
  78. }
  79.  
  80. private VoxelShape calculateShape(BlockState blockState) {
  81. VoxelShape voxelShape = SHAPE_DOT;
  82.  
  83. for (Direction direction: Direction.Plane.HORIZONTAL)
  84. if (blockState.getValue(PROPERTY_BY_DIRECTION.get(direction)))
  85. voxelShape = Shapes.or(voxelShape, SHAPE_BY_DIRECTION.get(direction));
  86.  
  87. return voxelShape;
  88. }
  89.  
  90. @Override
  91. protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
  92. builder.add(NORTH, SOUTH, WEST, EAST, POWERED, SOURCE_DISTANCE);
  93. }
  94.  
  95. @Override
  96. public @NotNull VoxelShape getShape(BlockState blockState, @NotNull BlockGetter blockGetter, @NotNull BlockPos blockPos, @NotNull CollisionContext collisionContext) {
  97. return SHAPES_CACHE.get(blockState.setValue(POWERED, Boolean.FALSE).setValue(SOURCE_DISTANCE, 0));
  98. }
  99.  
  100. @Nullable
  101. @Override
  102. public BlockState getStateForPlacement(BlockPlaceContext blockPlaceContext) {
  103. return getConnectionState(blockPlaceContext.getLevel(), CROSS_STATE, blockPlaceContext.getClickedPos());
  104. }
  105.  
  106. private BlockState getConnectionState(BlockGetter blockGetter, BlockState blockState, BlockPos blockPos) {
  107. boolean dot = isDot(blockState);
  108. blockState = getMissingConnections(blockGetter, defaultBlockState().setValue(POWERED, Boolean.FALSE).setValue(SOURCE_DISTANCE, 0), blockPos);
  109.  
  110. if (dot && isDot(blockState))
  111. return blockState;
  112.  
  113. boolean north = blockState.getValue(NORTH), south = blockState.getValue(SOUTH), west = blockState.getValue(WEST), east = blockState.getValue(EAST);
  114.  
  115. if (!north && !south && !west)
  116. blockState.setValue(WEST, Boolean.TRUE);
  117.  
  118. if (!north && !south && !east)
  119. blockState.setValue(EAST, Boolean.TRUE);
  120.  
  121. if (!north && !west && !east)
  122. blockState.setValue(NORTH, Boolean.TRUE);
  123.  
  124. if (!south && !west && !east)
  125. blockState.setValue(SOUTH, Boolean.TRUE);
  126.  
  127. return blockState;
  128. }
  129.  
  130. private BlockState getMissingConnections(BlockGetter blockGetter, BlockState blockState, BlockPos blockPos) {
  131. for (Direction direction: Direction.Plane.HORIZONTAL)
  132. if (!blockState.getValue(PROPERTY_BY_DIRECTION.get(direction))) {
  133. boolean isConnecting = getConnectingSide(blockGetter, blockPos, direction);
  134. blockState.setValue(PROPERTY_BY_DIRECTION.get(direction), isConnecting);
  135. }
  136.  
  137. return blockState;
  138. }
  139.  
  140. private Boolean getConnectingSide(BlockGetter blockGetter, BlockPos blockPos, Direction direction) {
  141. BlockState relativeBlockState = blockGetter.getBlockState(blockPos.relative(direction));
  142.  
  143. return relativeBlockState.getBlock() instanceof Component;
  144. }
  145.  
  146. private boolean isDot(BlockState blockState) {
  147. boolean dot = false;
  148. for (Direction direction: Direction.Plane.HORIZONTAL)
  149. dot |= blockState.getValue(PROPERTY_BY_DIRECTION.get(direction));
  150. return !dot;
  151. }
  152.  
  153. private void updateSourceDistance(Level level, BlockPos blockPos, BlockState blockState) {
  154. int i = calculateTargetStrength(level, blockPos);
  155. if (blockState.getValue(SOURCE_DISTANCE) != i) {
  156. if (level.getBlockState(blockPos) == blockState)
  157. level.setBlock(blockPos, blockState.setValue(SOURCE_DISTANCE, i).setValue(POWERED, i != 0), Block.UPDATE_CLIENTS);
  158.  
  159. Set<BlockPos> blockPosSet = Sets.newHashSet();
  160. blockPosSet.add(blockPos);
  161.  
  162. for (Direction direction: Direction.Plane.HORIZONTAL)
  163. blockPosSet.add(blockPos.relative(direction));
  164. for (BlockPos blockPos1: blockPosSet)
  165. level.updateNeighborsAt(blockPos1, this);
  166. }
  167. }
  168.  
  169. private int calculateTargetStrength(Level level, BlockPos blockPos) {
  170. int i = 0;
  171.  
  172. for (Direction direction: Direction.Plane.HORIZONTAL) {
  173. BlockState blockState = level.getBlockState(blockPos.relative(direction));
  174. if (blockState.getBlock() instanceof Component component)
  175. i = Math.min(i, component.getSourceDistance(blockState));
  176. }
  177.  
  178. return i;
  179. }
  180.  
  181. @Override
  182. public int getSourceDistance(BlockState blockState) {
  183. return blockState.getValue(SOURCE_DISTANCE);
  184. }
  185.  
  186. private void checkCornerChangeAt(Level level, BlockPos blockPos) {
  187. if (level.getBlockState(blockPos).getBlock() instanceof Component) {
  188. level.updateNeighborsAt(blockPos, this);
  189.  
  190. for (Direction direction: Direction.values())
  191. level.updateNeighborsAt(blockPos.relative(direction), this);
  192. }
  193. }
  194.  
  195. @Override
  196. public void onPlace(BlockState blockState, Level level, BlockPos blockPos, BlockState blockState1, boolean bool) {
  197. if (!blockState1.is(blockState.getBlock()) && !level.isClientSide) {
  198. updateSourceDistance(level, blockPos, blockState);
  199.  
  200. for (Direction direction: Direction.Plane.VERTICAL)
  201. level.updateNeighborsAt(blockPos.relative(direction), this);
  202.  
  203. updateNeighborsOfNeighboringWires(level, blockPos);
  204. }
  205. }
  206.  
  207. @Override
  208. public void onRemove(BlockState blockState, Level level, BlockPos blockPos, BlockState blockState1, boolean bool) {
  209. if (!bool && !blockState.is(blockState1.getBlock())) {
  210. super.onRemove(blockState, level, blockPos, blockState1, false);
  211.  
  212. if (!level.isClientSide) {
  213. for (Direction direction: Direction.values())
  214. level.updateNeighborsAt(blockPos.relative(direction), this);
  215.  
  216. updateSourceDistance(level, blockPos, blockState);
  217. updateNeighborsOfNeighboringWires(level, blockPos);
  218. }
  219. }
  220. }
  221.  
  222. private void updateNeighborsOfNeighboringWires(Level level, BlockPos blockPos) {
  223. for (Direction direction: Direction.Plane.HORIZONTAL)
  224. checkCornerChangeAt(level, blockPos.relative(direction));
  225. }
  226.  
  227. @Override
  228. public void neighborChanged(BlockState blockState, Level level, BlockPos blockPos, Block block, BlockPos blockPos1, boolean bool) {
  229. if (!level.isClientSide)
  230. updateSourceDistance(level, blockPos, blockState);
  231. }
  232.  
  233. @Override
  234. public boolean isSignalSource(Direction direction) {
  235. return false;
  236. }
  237.  
  238. @Override
  239. public boolean isConnectable(BlockState blockState, Direction direction) {
  240. return false;
  241. }
  242. }
Add Comment
Please, Sign In to add comment