Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.

end gateway

Lera 94ee311d 07ee04f2

+70 -10
+4 -8
common/src/main/java/net/lerariemann/infinity/dimensions/features/surface_structures/RandomEndGateway.java
··· 3 3 import net.lerariemann.infinity.dimensions.RandomFeaturesList; 4 4 import net.lerariemann.infinity.dimensions.features.Placement; 5 5 import net.lerariemann.infinity.dimensions.features.RandomisedFeature; 6 + import net.lerariemann.infinity.util.core.ConfigType; 6 7 import net.minecraft.nbt.NbtCompound; 7 - import net.minecraft.nbt.NbtInt; 8 8 import net.minecraft.nbt.NbtList; 9 9 10 10 public class RandomEndGateway extends RandomisedFeature { 11 11 public RandomEndGateway(RandomFeaturesList parent) { 12 12 super(parent, "gateway"); 13 - id = "end_gateway"; 13 + id = "infinity:end_gateway"; 14 14 savePlacement(); 15 15 } 16 16 ··· 22 22 23 23 public NbtCompound feature() { 24 24 NbtCompound config = new NbtCompound(); 25 - config.putBoolean("exact", PROVIDER.roll(random, "exact_gateways")); 26 - NbtList exit = new NbtList(); 27 - exit.add(NbtInt.of(random.nextInt(-2048, 2048))); 28 - exit.add(NbtInt.of(random.nextInt(daddy.min_y, daddy.min_y + daddy.height))); 29 - exit.add(NbtInt.of(random.nextInt(-2048, 2048))); 30 - config.put("exit", exit); 25 + config.putInt("spread", (int)(1000 * Math.pow(2, 2 * random.nextDouble() - 1))); 26 + if (PROVIDER.roll(random, "gateways_random_block")) addRandomBlock(config, "block", ConfigType.FULL_BLOCKS); 31 27 return feature(config); 32 28 } 33 29 }
+62
common/src/main/java/net/lerariemann/infinity/features/RandomEndGatewayFeature.java
··· 1 + package net.lerariemann.infinity.features; 2 + 3 + import com.mojang.serialization.Codec; 4 + import com.mojang.serialization.codecs.RecordCodecBuilder; 5 + import net.minecraft.block.BlockState; 6 + import net.minecraft.block.Blocks; 7 + import net.minecraft.block.entity.EndGatewayBlockEntity; 8 + import net.minecraft.util.dynamic.Codecs; 9 + import net.minecraft.util.math.BlockPos; 10 + import net.minecraft.world.StructureWorldAccess; 11 + import net.minecraft.world.gen.feature.*; 12 + import net.minecraft.world.gen.feature.util.FeatureContext; 13 + 14 + import java.util.Optional; 15 + 16 + public class RandomEndGatewayFeature extends Feature<RandomEndGatewayFeature.Config> { 17 + public RandomEndGatewayFeature(Codec<RandomEndGatewayFeature.Config> codec) { 18 + super(codec); 19 + } 20 + 21 + @Override 22 + public boolean generate(FeatureContext<RandomEndGatewayFeature.Config> context) { 23 + BlockPos origin = context.getOrigin(); 24 + StructureWorldAccess structureWorldAccess = context.getWorld(); 25 + RandomEndGatewayFeature.Config config = context.getConfig(); 26 + BlockState bedrock = config.block.orElse(Blocks.BEDROCK.getDefaultState()); 27 + for (BlockPos bp : BlockPos.iterate(origin.add(-1, -2, -1), origin.add(1, 2, 1))) { 28 + boolean bl = bp.getX() == origin.getX(); 29 + boolean bl2 = bp.getY() == origin.getY(); 30 + boolean bl3 = bp.getZ() == origin.getZ(); 31 + boolean bl4 = Math.abs(bp.getY() - origin.getY()) == 2; 32 + BlockState localFluid = structureWorldAccess.getFluidState(bp).getBlockState().getBlock().getDefaultState(); 33 + if (bl && bl2 && bl3) { 34 + BlockPos destination = new BlockPos(bp.getX() + context.getRandom().nextBetween(-config.spread, config.spread), 35 + bp.getY(), bp.getZ() + context.getRandom().nextBetween(-config.spread, config.spread)); 36 + destination = structureWorldAccess.getWorldBorder().clamp(destination); 37 + this.setBlockState(structureWorldAccess, bp, Blocks.END_GATEWAY.getDefaultState()); 38 + if (structureWorldAccess.getBlockEntity(bp) instanceof EndGatewayBlockEntity egbe) { 39 + egbe.setExitPortalPos(destination, false); 40 + } 41 + } else if (bl2) { 42 + this.setBlockState(structureWorldAccess, bp, localFluid); 43 + } else if (bl4 && bl && bl3) { 44 + this.setBlockState(structureWorldAccess, bp, bedrock); 45 + } else if ((bl || bl3) && !bl4) { 46 + this.setBlockState(structureWorldAccess, bp, bedrock); 47 + } else { 48 + this.setBlockState(structureWorldAccess, bp, localFluid); 49 + } 50 + } 51 + 52 + return true; 53 + } 54 + 55 + public record Config(int spread, Optional<BlockState> block) implements FeatureConfig { 56 + public static final Codec<RandomEndGatewayFeature.Config> CODEC = RecordCodecBuilder.create(instance -> instance.group( 57 + (Codecs.rangedInt(1, 30000000).fieldOf("spread")).forGetter(a -> a.spread), 58 + (BlockState.CODEC.optionalFieldOf("block")).forGetter(a -> a.block)).apply( 59 + instance, RandomEndGatewayFeature.Config::new)); 60 + } 61 + } 62 +
+2
common/src/main/java/net/lerariemann/infinity/registry/core/ModFeatures.java
··· 21 21 public static RegistrySupplier<RandomRoundMushroomFeature> RANDOM_ROUND_MUSHROOM; 22 22 public static RegistrySupplier<RandomCeilingBlobFeature> RANDOM_CEILING_BLOB; 23 23 public static RegistrySupplier<RandomBonusChestFeature> RANDOM_BONUS_CHEST; 24 + public static RegistrySupplier<RandomEndGatewayFeature> RANDOM_END_GATEWAY; 24 25 public static RegistrySupplier<RandomCubeFeature> RANDOM_CUBE; 25 26 public static RegistrySupplier<RandomShapeFeature> RANDOM_STAR; 26 27 public static RegistrySupplier<TextFeature> RANDOM_TEXT; ··· 46 47 RANDOM_TEXT = register("random_text", new TextFeature(TextFeature.Config.CODEC)); 47 48 PORTAL_SETUPPER = register("portal_setupper", new RandomPortalSetupper((RandomPortalSetupper.Config.CODEC))); 48 49 RANDOM_BONUS_CHEST = register("bonus_chest", new RandomBonusChestFeature(RandomBonusChestFeature.Config.CODEC)); 50 + RANDOM_END_GATEWAY = register("end_gateway", new RandomEndGatewayFeature(RandomEndGatewayFeature.Config.CODEC)); 49 51 WONKY_TRUNK = TRUNKS.register("wonky", () -> new TrunkPlacerType<>(WonkyTrunkPlacer.CODEC)); 50 52 FEATURES.register(); 51 53 TRUNKS.register();
+1 -1
common/src/main/resources/assets/infinity/lang/en_us.json
··· 242 242 "config.infinity.rootChances.features_rules.scatter_ores.description": "This setting changes how often to toggle between \"ore\" and \"scattered_ore\" types of ore deposit generation.", 243 243 "config.infinity.rootChances.features_rules.scatter_end_spikes.description": "When you have end spikes in a random dimension, this is a chance they will be all over the place like in pre-1.9 and not in a perfect circle.", 244 244 "config.infinity.rootChances.features_rules.cage_crystals.description": "This setting controls the percentage of spikes that have their end crystal in a cage.", 245 - "config.infinity.rootChances.features_rules.exact_gateways.description": "This setting controls the chance that an End Gateway will teleport you to exact coordinates without regards to if you'll get stuck in a wall there. Otherwise, it will at least try to find a safe spot nearby.", 245 + "config.infinity.rootChances.features_rules.gateways_bedrock.description": "This setting controls the chance that End Gateways will use a random block instead of bedrock.", 246 246 "config.infinity.rootChances.features_rules.colourful_shapes.description": "This setting controls whether the large balls that spawn being of one random block or of a bunch of colored blocks.", 247 247 "config.infinity.rootChances.features_rules.banded_shapes.description": "This setting controls whether large balls made of coloured blocks are arranged in a perlin noise map or in diagonal bands.", 248 248 "config.infinity.rootChances.dimension_type.piglin_safe.description": "This setting controls the percentage of dimensions where Piglins are not converted into Zombie Piglins.",
+1 -1
common/src/main/resources/config/infinity.json
··· 92 92 "scatter_ores": 0.2, 93 93 "scatter_end_spikes": 0.67, 94 94 "cage_crystals": 0.2, 95 - "exact_gateways": 0.2, 95 + "gateways_random_block": 0.8, 96 96 "colourful_shapes": 0.5, 97 97 "banded_shapes": 0.5 98 98 },