Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
at master 144 lines 7.1 kB view raw
1package net.lerariemann.infinity.compat; 2 3//? if <1.21.2 { 4/*import com.simibubi.create.api.contraption.train.PortalTrackProvider; 5import com.simibubi.create.content.trains.track.AllPortalTracks; 6import com.simibubi.create.content.trains.track.TrackBlock; 7import com.simibubi.create.content.trains.track.TrackShape; 8import net.createmod.catnip.math.BlockFace; 9*///?} else if fabric { 10import com.zurrtum.create.api.contraption.train.PortalTrackProvider; 11import com.zurrtum.create.catnip.math.BlockFace; 12import com.zurrtum.create.content.trains.track.AllPortalTracks; 13import com.zurrtum.create.content.trains.track.TrackBlock; 14import com.zurrtum.create.content.trains.track.TrackShape; 15//?} 16//? if <1.21.2 || fabric { 17import net.lerariemann.infinity.block.custom.RailHelper; 18import net.lerariemann.infinity.block.entity.InfinityPortalBlockEntity; 19import net.lerariemann.infinity.registry.core.ModBlocks; 20import net.lerariemann.infinity.util.InfinityMethods; 21import net.lerariemann.infinity.util.VersionMethods; 22import net.minecraft.core.BlockPos; 23import net.minecraft.core.Direction; 24import net.minecraft.core.registries.BuiltInRegistries; 25import net.minecraft.server.MinecraftServer; 26import net.minecraft.server.dedicated.DedicatedServer; 27import net.minecraft.server.level.ServerLevel; 28import net.minecraft.world.level.Level; 29import net.minecraft.world.level.block.Block; 30import net.minecraft.world.level.block.Blocks; 31import net.minecraft.world.level.block.NetherPortalBlock; 32import net.minecraft.world.level.block.state.BlockState; 33import net.minecraft.world.level.block.state.properties.BlockStateProperties; 34 35import java.util.Optional; 36import java.util.Set; 37//?} 38 39public class CreateCompat { 40 //? if <1.21.2 || fabric { 41 private static PortalTrackProvider.Exit infinityPortalProvider(ServerLevel worldFrom, BlockFace blockFace) { 42 if (!VersionMethods.allowNether(worldFrom.getServer())) { 43 return null; 44 } 45 BlockPos posFrom = blockFace.getConnectedPos(); 46 if (worldFrom.getBlockEntity(posFrom) instanceof InfinityPortalBlockEntity ipbe 47 && ipbe.isConnectedBothSides()) { //we only allow trains through if portals are in sync 48 ServerLevel worldTo = ipbe.getDimensionAsWorld(); 49 BlockPos posTo = ipbe.getOtherSidePos(); 50 assert worldTo != null; 51 assert posTo != null; 52 53 BlockPos correctedPos = getCorrectedPos(worldFrom, posFrom, worldTo, posTo); 54 55 Direction targetDirection = blockFace.getFace(); 56 Direction.Axis axisTo = worldTo.getBlockState(posTo).getValue(BlockStateProperties.HORIZONTAL_AXIS); 57 if (targetDirection.getAxis().equals(axisTo)) { 58 targetDirection = targetDirection.getClockWise(); 59 } 60 return new PortalTrackProvider.Exit(worldTo, new BlockFace(correctedPos.relative(targetDirection), targetDirection.getOpposite())); 61 } 62 return null; 63 } 64 65 public static BlockPos getCorrectedPos(ServerLevel worldFrom, BlockPos posFrom, ServerLevel worldTo, BlockPos posTo) { 66 Direction.Axis axisFrom = worldFrom.getBlockState(posFrom).getValue(BlockStateProperties.HORIZONTAL_AXIS); 67 boolean fromX = axisFrom.equals(Direction.Axis.X); 68 69 BlockPos maxHere = getBound(worldFrom, posFrom, axisFrom, true); 70 int max_here = fromX ? maxHere.getX() : maxHere.getZ(); 71 BlockPos minHere = getBound(worldFrom, posFrom, axisFrom, false); 72 int min_here = fromX ? minHere.getX() : minHere.getZ(); 73 74 Direction.Axis axisTo = worldTo.getBlockState(posTo).getValue(BlockStateProperties.HORIZONTAL_AXIS); 75 boolean toX = axisTo.equals(Direction.Axis.X); 76 77 BlockPos maxThere = getBound(worldTo, posTo, axisTo, true); 78 int max_there = toX ? maxThere.getX() : maxThere.getZ(); 79 BlockPos minThere = getBound(worldTo, posTo, axisTo, false); 80 int min_there = toX ? minThere.getX() : minThere.getZ(); 81 82 int here = fromX ? posFrom.getX() : posFrom.getZ(); 83 int there; 84 if (max_there - min_there == max_here - min_here) { 85 there = min_there + (here - min_here); 86 } 87 there = min_there + (int)((here - min_here)*(max_there-min_there)/(float)(max_here-min_here)); //might not be super good but feels decent 88 89 return new BlockPos(toX ? there : posTo.getX(), posTo.getY(), toX ? posTo.getZ() : there); 90 } 91 92 public static BlockPos getBound(ServerLevel world, BlockPos pos, Direction.Axis axis, boolean positive) { 93 BlockPos bp = pos; 94 int i = positive ? 1 : -1; 95 while (world.getBlockState(bp).getBlock() instanceof NetherPortalBlock) { 96 bp = bp.relative(axis, i); 97 } 98 return bp.relative(axis, -i); 99 } 100 101 public static void register() { 102 AllPortalTracks.tryRegisterIntegration(InfinityMethods.getId("neither_portal"), CreateCompat::infinityPortalProvider); 103 } 104 105 public static void tryModifyRails(InfinityPortalBlockEntity ipbe) { 106 Level w = ipbe.getLevel(); 107 if (w instanceof ServerLevel worldFrom) { 108 BlockPos posFrom = ipbe.getBlockPos(); 109 BlockState state = worldFrom.getBlockState(posFrom); 110 if (!state.is(ModBlocks.PORTAL.get())) return; 111 Set<Direction> toCheck = state.getValue(BlockStateProperties.HORIZONTAL_AXIS).equals(Direction.Axis.X) ? 112 Set.of(Direction.NORTH, Direction.SOUTH) : Set.of(Direction.EAST, Direction.WEST); 113 for (Direction dir : toCheck) { 114 BlockPos posTrack = posFrom.relative(dir); 115 BlockState bs = worldFrom.getBlockState(posTrack); 116 if (bs.getBlock() instanceof TrackBlock) 117 modifyRails(ipbe, worldFrom, posTrack, bs); 118 } 119 } 120 } 121 122 public static void modifyRails(InfinityPortalBlockEntity ipbe, ServerLevel worldFrom, 123 BlockPos posTrack, BlockState bs) { 124 if (ipbe.isConnectedBothSides()) { 125 if (!bs.hasProperty(TrackBlock.SHAPE)) return; 126 worldFrom.setBlockAndUpdate(posTrack, ModBlocks.RAIL_HELPER.get().defaultBlockState()); 127 RailHelper.RHBEntity e = RailHelper.getBlockEntity(worldFrom, posTrack); 128 e.trackBlock = BuiltInRegistries.BLOCK.getKey(bs.getBlock()); 129 e.shape = switch (bs.getValue(TrackBlock.SHAPE)) { 130 case TN, TS -> "zo"; 131 default -> "xo"; 132 }; 133 } 134 worldFrom.setBlockAndUpdate(posTrack, Blocks.AIR.defaultBlockState()); 135 } 136 public static void reattachRails(ServerLevel world, BlockPos pos, RailHelper.RHBEntity e) { 137 BlockState bs; 138 Optional<Block> b = BuiltInRegistries.BLOCK.getOptional(e.trackBlock); 139 if (b.isEmpty() || !(b.get() instanceof TrackBlock)) bs = Blocks.AIR.defaultBlockState(); 140 else bs = b.get().defaultBlockState().setValue(TrackBlock.SHAPE, e.shape.equals("zo") ? TrackShape.ZO : TrackShape.XO); 141 world.setBlockAndUpdate(pos, bs); 142 } 143 //?} 144}