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

better f4

Lera ba651e69 aa545535

+66 -28
+8 -3
common/src/main/java/net/lerariemann/infinity/InfinityModClient.java
··· 2 2 3 3 import dev.architectury.registry.client.keymappings.KeyMappingRegistry; 4 4 import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; 5 - import net.lerariemann.infinity.util.screen.F4Screen; 5 + import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; 6 + import net.lerariemann.infinity.item.F4Item; 6 7 import net.lerariemann.infinity.registry.core.ModEntities; 7 8 import net.lerariemann.infinity.registry.core.ModItems; 8 9 import net.lerariemann.infinity.registry.var.ModPayloads; 9 10 import net.lerariemann.infinity.registry.var.ModScreenHandlers; 10 11 import net.minecraft.client.option.KeyBinding; 11 12 import net.minecraft.client.util.InputUtil; 13 + import net.minecraft.item.ItemStack; 12 14 import net.minecraft.util.Hand; 15 + import net.minecraft.util.TypedActionResult; 13 16 import net.minecraft.util.math.noise.DoublePerlinNoiseSampler; 14 17 import net.minecraft.util.math.random.CheckedRandom; 15 18 import org.lwjgl.glfw.GLFW; 16 19 17 20 public class InfinityModClient { 18 21 public final static DoublePerlinNoiseSampler sampler = DoublePerlinNoiseSampler.create(new CheckedRandom(0L), -3, 1.0, 1.0, 1.0, 0.0); 19 - public static KeyBinding f4ConfigKey = new KeyBinding("key.infinity.f4_config", 22 + public static KeyBinding f4ConfigKey = new KeyBinding("key.infinity.f4", 20 23 InputUtil.Type.KEYSYM, 21 24 GLFW.GLFW_KEY_F4, 22 25 "key.categories.misc"); ··· 29 32 ClientTickEvents.END_CLIENT_TICK.register(client -> { 30 33 while (f4ConfigKey.wasPressed()) if (client.player != null 31 34 && client.player.getStackInHand(Hand.MAIN_HAND).isOf(ModItems.F4.get())) { 32 - client.setScreen(F4Screen.of(client.player)); 35 + ClientPlayNetworking.send(ModPayloads.DeployF4.INSTANCE); 36 + TypedActionResult<ItemStack> result = F4Item.deploy(client.world, client.player, Hand.MAIN_HAND); 37 + client.player.setStackInHand(Hand.MAIN_HAND, result.getValue()); 33 38 } 34 39 }); 35 40 }
+26 -10
common/src/main/java/net/lerariemann/infinity/item/F4Item.java
··· 5 5 import net.lerariemann.infinity.registry.core.ModComponentTypes; 6 6 import net.lerariemann.infinity.registry.core.ModItems; 7 7 import net.lerariemann.infinity.util.InfinityMethods; 8 + import net.lerariemann.infinity.util.screen.F4Screen; 8 9 import net.lerariemann.infinity.util.teleport.InfinityPortal; 9 10 import net.minecraft.block.BlockState; 10 11 import net.minecraft.block.Blocks; 11 12 import net.minecraft.block.NetherPortalBlock; 13 + import net.minecraft.client.MinecraftClient; 14 + import net.minecraft.client.network.ClientPlayerEntity; 12 15 import net.minecraft.component.ComponentMap; 13 16 import net.minecraft.entity.player.PlayerEntity; 14 17 import net.minecraft.item.Item; 15 18 import net.minecraft.item.ItemStack; 16 19 import net.minecraft.item.ItemUsageContext; 17 20 import net.minecraft.item.tooltip.TooltipType; 21 + import net.minecraft.sound.SoundCategory; 18 22 import net.minecraft.sound.SoundEvents; 19 23 import net.minecraft.state.property.Properties; 20 24 import net.minecraft.text.MutableText; ··· 98 102 } 99 103 useCharges -= obsNotReplaced; 100 104 101 - player.playSound(SoundEvents.BLOCK_BELL_USE, 1, 0.75f); 105 + world.playSound(player, player.getBlockPos(), SoundEvents.BLOCK_BELL_USE, SoundCategory.BLOCKS, 1, 0.75f); 102 106 stack.applyComponentsFrom(ComponentMap.builder() 103 107 .add(ModComponentTypes.CHARGE.get(), charges - useCharges).build()); 104 108 return stack; ··· 106 110 107 111 @Override 108 112 public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) { 113 + if (player instanceof ClientPlayerEntity clientPlayer) { 114 + MinecraftClient.getInstance().setScreen(F4Screen.of(clientPlayer)); 115 + } 116 + return TypedActionResult.success(player.getStackInHand(hand)); 117 + } 118 + 119 + public static TypedActionResult<ItemStack> deploy(World world, PlayerEntity player, Hand hand) { 109 120 Direction dir = player.getHorizontalFacing(); 110 121 Direction.Axis dir2 = dir.rotateClockwise(Direction.Axis.Y).getAxis(); 111 122 BlockPos lowerCenter = player.getBlockPos().offset(dir, 4); ··· 128 139 boolean positionFound = true; 129 140 for (i = 0; i <= 8 && !world.isOutOfHeightLimit(lowerY + i + size_y); i++) { 130 141 positionFound = true; 131 - for (int j = 0; j <= size_y+1; j++) for (int k = -1; k <= size_x; k++) { 142 + for (int j = 0; j <= size_y+1 && positionFound; j++) for (int k = -1; k <= size_x; k++) { 132 143 BlockState bs = world.getBlockState(lowerCenter.up(i+j-1).offset(dir2, k - (size_x /2))); 133 - if (!bs.isAir() && !bs.isOf(Blocks.OBSIDIAN)) { 134 - i += j; 135 - positionFound = false; 136 - break; 144 + if (bs.isReplaceable()) continue; 145 + if (bs.isOf(Blocks.OBSIDIAN)) { 146 + if (j == 0 || j == size_y+1 || k == -1 || k == size_x) continue; 147 + i += j-1; 137 148 } 149 + else i += j; 150 + positionFound = false; 151 + break; 138 152 } 139 153 if (positionFound) break; 140 154 } ··· 175 189 //validating the place position 176 190 for (int j = -1; j <= size_y; j++) for (int k = -1; k <= size_x; k++) { 177 191 bs = world.getBlockState(pos.up(j).offset(dir2, k - (size_x /2))); 178 - if (!bs.isAir() && !bs.isOf(Blocks.OBSIDIAN)) { 179 - return ActionResult.FAIL; 180 - } 192 + if (bs.isOf(Blocks.OBSIDIAN) && (j == -1 || j == size_y || k == -1 || k == size_x)) continue; 193 + if (!bs.isReplaceable()) return ActionResult.FAIL; 181 194 } 182 195 183 196 ItemStack newStack = placePortal(world, player, context.getStack().copy(), pos, ··· 254 267 } 255 268 int obsidian = 0; 256 269 for (BlockPos bp : toRemove) if (!toLeave.contains(bp)) { //double check since we're checking the corners twice 257 - world.removeBlock(bp, false); 270 + world.setBlockState(bp, Blocks.AIR.getDefaultState(), 3, 0); 258 271 obsidian++; 259 272 } 273 + for (int i = 0; i <= portal.width; i++) for (int j = -1; j <= portal.height; j++) 274 + world.setBlockState(portal.lowerLeft.offset(axis, i).up(j), Blocks.AIR.getDefaultState(), 3, 0); 260 275 stack.applyComponentsFrom(ComponentMap.builder() 261 276 .add(ModComponentTypes.CHARGE.get(), getCharge(stack) + obsidian).build()); 277 + world.playSound(null, origin, SoundEvents.BLOCK_GLASS_BREAK, SoundCategory.BLOCKS, 1, 0.75f); 262 278 return stack; 263 279 } 264 280 }
+31 -14
common/src/main/java/net/lerariemann/infinity/registry/var/ModPayloads.java
··· 7 7 import net.lerariemann.infinity.access.InfinityOptionsAccess; 8 8 import net.lerariemann.infinity.access.WorldRendererAccess; 9 9 import net.lerariemann.infinity.iridescence.Iridescence; 10 + import net.lerariemann.infinity.item.F4Item; 10 11 import net.lerariemann.infinity.registry.core.ModComponentTypes; 11 12 import net.lerariemann.infinity.registry.core.ModItems; 12 13 import net.lerariemann.infinity.util.loading.DimensionGrabber; ··· 22 23 import net.minecraft.network.codec.PacketCodec; 23 24 import net.minecraft.network.codec.PacketCodecs; 24 25 import net.minecraft.network.packet.CustomPayload; 25 - import net.minecraft.server.MinecraftServer; 26 26 import net.minecraft.server.network.ServerPlayerEntity; 27 27 import net.minecraft.server.world.ServerWorld; 28 + import net.minecraft.util.Hand; 28 29 import net.minecraft.util.Identifier; 30 + import net.minecraft.util.TypedActionResult; 29 31 30 32 import java.nio.file.Path; 31 33 import java.util.Objects; ··· 129 131 } 130 132 131 133 public record F4Payload(int slot, int width, int height) implements CustomPayload { 132 - public static final CustomPayload.Id<F4Payload> ID = new CustomPayload.Id<>(InfinityMethods.getId("f4")); 134 + public static final CustomPayload.Id<F4Payload> ID = new CustomPayload.Id<>(InfinityMethods.getId("receive_f4")); 133 135 public static final PacketCodec<RegistryByteBuf, F4Payload> CODEC = PacketCodec.tuple( 134 136 PacketCodecs.VAR_INT, F4Payload::slot, 135 137 PacketCodecs.VAR_INT, F4Payload::width, ··· 141 143 } 142 144 } 143 145 public static void receiveF4(F4Payload payload, ServerPlayNetworking.Context context) { 144 - try (MinecraftServer server = context.server()) { 145 - server.execute(() -> { 146 - ItemStack st = context.player().getInventory().getStack(payload.slot); 147 - if (st.isOf(ModItems.F4.get())) { 148 - ItemStack newStack = st.copy(); 149 - newStack.applyComponentsFrom(ComponentMap.builder() 150 - .add(ModComponentTypes.SIZE_X.get(), Math.clamp(payload.width, 1, 21)) 151 - .add(ModComponentTypes.SIZE_Y.get(), Math.clamp(payload.height, 1, 21)) 152 - .build()); 153 - context.player().getInventory().setStack(payload.slot, newStack); 154 - } 155 - }); 146 + ItemStack st = context.player().getInventory().getStack(payload.slot); 147 + if (st.isOf(ModItems.F4.get())) { 148 + ItemStack newStack = st.copy(); 149 + newStack.applyComponentsFrom(ComponentMap.builder() 150 + .add(ModComponentTypes.SIZE_X.get(), Math.clamp(payload.width, 1, 21)) 151 + .add(ModComponentTypes.SIZE_Y.get(), Math.clamp(payload.height, 1, 21)) 152 + .build()); 153 + context.player().getInventory().setStack(payload.slot, newStack); 154 + } 155 + } 156 + public record DeployF4() implements CustomPayload { 157 + public static final DeployF4 INSTANCE = new DeployF4(); 158 + public static final CustomPayload.Id<DeployF4> ID = new CustomPayload.Id<>(InfinityMethods.getId("deploy_f4")); 159 + public static final PacketCodec<RegistryByteBuf, DeployF4> CODEC = PacketCodec.unit(INSTANCE); 160 + @Override 161 + public CustomPayload.Id<? extends CustomPayload> getId() { 162 + return ID; 163 + } 164 + } 165 + public static void deployF4(DeployF4 payload, ServerPlayNetworking.Context context) { 166 + ServerPlayerEntity player = context.player(); 167 + ItemStack st = player.getStackInHand(Hand.MAIN_HAND); 168 + if (st.isOf(ModItems.F4.get())) { 169 + TypedActionResult<ItemStack> result = F4Item.deploy(player.getServerWorld(), player, Hand.MAIN_HAND); 170 + player.setStackInHand(Hand.MAIN_HAND, result.getValue()); 156 171 } 157 172 } 158 173 ··· 162 177 PayloadTypeRegistry.playS2C().register(ShaderRePayload.ID, ShaderRePayload.CODEC); 163 178 PayloadTypeRegistry.playS2C().register(StarsRePayLoad.ID, StarsRePayLoad.CODEC); 164 179 PayloadTypeRegistry.playC2S().register(F4Payload.ID, F4Payload.CODEC); 180 + PayloadTypeRegistry.playC2S().register(DeployF4.ID, DeployF4.CODEC); 165 181 ServerPlayNetworking.registerGlobalReceiver(F4Payload.ID, ModPayloads::receiveF4); 182 + ServerPlayNetworking.registerGlobalReceiver(DeployF4.ID, ModPayloads::deployF4); 166 183 } 167 184 168 185 public static void registerPayloadsClient() {
+1 -1
common/src/main/resources/assets/infinity/lang/en_us.json
··· 109 109 "item.infinity.star_of_lang": "Star of Lang", 110 110 "item.infinity.iridescent_star": "Iridescent Star", 111 111 "item.infinity.f4": "F4", 112 - "key.infinity.f4_config": "Open F4 config menu", 112 + "key.infinity.f4": "Place a Nether Portal", 113 113 "lore.infinity.altar": "This block can be crafted by throwing a Lectern into an Infinity Portal. Using a diamond on it will play a fun animation!", 114 114 "lore.infinity.ant": "This strange block rapidly moves, changing White Concrete to Black Concrete and back again, referencing \"Langton's ant\".", 115 115 "lore.infinity.book_box": "This block can be found in the Infinite Library. Using it will give you a randomly generated book based on the block's position.",