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