Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
at master 170 lines 6.9 kB view raw
1package net.lerariemann.infinity.block.custom; 2 3import net.lerariemann.infinity.registry.core.ModBlocks; 4import net.lerariemann.infinity.util.platform.InfinityPlatform; 5import net.lerariemann.infinity.util.VersionMethods; 6import net.lerariemann.infinity.util.var.BishopBattle; 7import net.minecraft.MethodsReturnNonnullByDefault; 8import net.minecraft.core.BlockPos; 9import net.minecraft.core.Direction; 10import net.minecraft.core.registries.BuiltInRegistries; 11import net.minecraft.server.level.ServerLevel; 12import net.minecraft.world.InteractionHand; 13import net.minecraft.world.InteractionResult; 14import net.minecraft.world.entity.player.Player; 15import net.minecraft.world.item.context.BlockPlaceContext; 16import net.minecraft.world.level.Level; 17import net.minecraft.world.level.block.Block; 18import net.minecraft.world.level.block.Blocks; 19import net.minecraft.world.level.block.HorizontalDirectionalBlock; 20import net.minecraft.world.level.block.state.BlockState; 21import net.minecraft.world.level.block.state.StateDefinition; 22import net.minecraft.world.phys.BlockHitResult; 23import org.jetbrains.annotations.NotNull; 24import org.jetbrains.annotations.Nullable; 25 26//? if >1.21 { 27import com.mojang.serialization.MapCodec; 28//?} 29//? if neoforge { 30/*import javax.annotation.ParametersAreNonnullByDefault; 31*///?} 32import java.util.Objects; 33import java.util.logging.Handler; 34 35@MethodsReturnNonnullByDefault 36//? if neoforge { 37/*@ParametersAreNonnullByDefault 38 *///?} 39public class AntBlock extends HorizontalDirectionalBlock { 40 //? if >1.21 { 41 public static final MapCodec<AntBlock> CODEC = simpleCodec(AntBlock::new); 42 //?} 43 44 public AntBlock(Properties settings) { 45 super(settings); 46 this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH)); 47 } 48 49 //? if >1.21 { 50 @Override 51 protected @NotNull MapCodec<? extends HorizontalDirectionalBlock> codec() { 52 return CODEC; 53 } 54 //?} 55 56 private static boolean inverseExists(Block down) { 57 var s = BuiltInRegistries.BLOCK.getKey(down); 58 var state = down.defaultBlockState(); 59 if (InfinityPlatform.INSTANCE.isInBlack(state)) { 60 return BuiltInRegistries.BLOCK.containsKey(VersionMethods.id(s.toString().replace("black", "white"))); 61 } 62 if (InfinityPlatform.INSTANCE.isInWhite(state)) { 63 return BuiltInRegistries.BLOCK.containsKey(VersionMethods.id(s.toString().replace("white", "black"))); 64 } 65 return false; 66 } 67 public static boolean isSafeToRecolor(Level world, BlockPos pos) { 68 return inverseExists(world.getBlockState(pos).getBlock()) && (world.getBlockEntity(pos) == null); 69 } 70 71 @Nullable 72 public static Block recolor(Block down, boolean toWhite) { 73 String s = VersionMethods.getNameAsString(BuiltInRegistries.BLOCK, down); 74 var state = down.defaultBlockState(); 75 if (InfinityPlatform.INSTANCE.isInBlack(state)) { 76 return toWhite ? VersionMethods.getFromRegistry(BuiltInRegistries.BLOCK, VersionMethods.id(s.replace("black", "white"))) : down; 77 } 78 if (InfinityPlatform.INSTANCE.isInWhite(state)) { 79 return toWhite ? down : VersionMethods.getFromRegistry(BuiltInRegistries.BLOCK, VersionMethods.id(s.replace("white", "black"))); 80 } 81 return null; 82 } 83 84 @Nullable 85 public static Clockwiseness getCW(Block down) { 86 String s = VersionMethods.getNameAsString(BuiltInRegistries.BLOCK, down); 87 if (s.contains("black")) { 88 return Clockwiseness.CCW; 89 } 90 if (s.contains("white")) { 91 return Clockwiseness.CW; 92 } 93 return null; 94 } 95 96 @Override 97 public void tick(BlockState state, ServerLevel world, BlockPos pos, net.minecraft.util.RandomSource random) { 98 super.tick(state, world, pos, random); 99 if (isSafeToRecolor(world, pos.below())) { 100 this.safeMove(state, world, pos); 101 } 102 } 103 104 @Override 105 public InteractionResult 106 //? if >1.21 { 107 useWithoutItem 108 //?} else { 109 /*use 110 *///?} 111 (BlockState state, Level world, BlockPos pos, Player player, 112 //? if <1.21 { 113 /*InteractionHand hand, 114 *///?} 115 BlockHitResult hit) { 116 return move(state, world, pos); 117 } 118 119 private InteractionResult move(BlockState blockState, Level world, BlockPos pos) { 120 if (isSafeToRecolor(world, pos.below())) return safeMove(blockState, world, pos); 121 return InteractionResult.FAIL; 122 } 123 124 private InteractionResult safeMove(BlockState blockState, Level world, BlockPos pos) { 125 BlockState down = world.getBlockState(pos.below()); 126 Clockwiseness clockwiseness = getCW(down.getBlock()); 127 if (clockwiseness == null) return InteractionResult.FAIL; 128 Direction direction = blockState.getValue(FACING); 129 Direction direction2 = clockwiseness == Clockwiseness.CW ? direction.getClockWise() : direction.getCounterClockWise(); 130 BlockPos blockPos = pos.relative(direction2); 131 if (world.isLoaded(blockPos) && world.getBlockState(blockPos).canBeReplaced()) { 132 switch (clockwiseness) { 133 case CW: 134 world.setBlock(pos.below(), Objects.requireNonNull(recolor(down.getBlock(), false)).withPropertiesOf(down), 19); 135 world.setBlock(pos, Blocks.AIR.defaultBlockState(), 3); 136 world.setBlock(blockPos, blockState.setValue(FACING, direction2), 3); 137 break; 138 case CCW: 139 world.setBlock(pos.below(), Objects.requireNonNull(recolor(down.getBlock(), true)).withPropertiesOf(down), 19); 140 world.setBlock(pos, Blocks.AIR.defaultBlockState(), 3); 141 world.setBlock(blockPos, blockState.setValue(FACING, direction2), 3); 142 } 143 } 144 return InteractionResult.SUCCESS; 145 } 146 147 @Override 148 public BlockState getStateForPlacement(BlockPlaceContext ctx) { 149 return this.defaultBlockState().setValue(FACING, ctx.getHorizontalDirection().getOpposite()); 150 } 151 @Override 152 public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { 153 //bishop miniboss battle 154 if (world instanceof ServerLevel level && world.getBlockState(pos.below()).is(ModBlocks.ALTAR.get())) { 155 world.removeBlock(pos, false); 156 world.removeBlock(pos.below(), false); 157 (new BishopBattle(level)).start(pos.below()); 158 } 159 else world.scheduleTick(pos, this, 1); 160 } 161 162 protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) { 163 builder.add(FACING); 164 } 165 166 public enum Clockwiseness { 167 CW, 168 CCW 169 } 170}