From b010c500d84e59ee30c58c766b954a6dc2a45423 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 17 May 2024 22:21:01 +0200 Subject: [PATCH 1/9] Various entity fixes: Ensure TNT doesn't bug into the ground, reset player entity flags properly (#4670) * Various entity fixes * actually update the tnt entity position * revert bad diff --- .../geyser/entity/EntityDefinitions.java | 3 ++- .../geysermc/geyser/entity/type/Entity.java | 5 +++- .../geyser/entity/type/ExpOrbEntity.java | 7 +++++ .../geyser/entity/type/TNTEntity.java | 12 ++++++++- .../entity/type/player/PlayerEntity.java | 26 +++++++++++++++++++ .../type/player/SessionPlayerEntity.java | 10 ++----- 6 files changed, 52 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 991b95571..21cc526dd 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -235,7 +235,7 @@ public final class EntityDefinitions { .addTranslator(MetadataType.BOOLEAN, (enderCrystalEntity, entityMetadata) -> enderCrystalEntity.setFlag(EntityFlag.SHOW_BOTTOM, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) // There is a base located on the ender crystal .build(); - EXPERIENCE_ORB = EntityDefinition.inherited(null, entityBase) + EXPERIENCE_ORB = EntityDefinition.inherited(ExpOrbEntity::new, entityBase) .type(EntityType.EXPERIENCE_ORB) .identifier("minecraft:xp_orb") .build(); @@ -297,6 +297,7 @@ public final class EntityDefinitions { TNT = EntityDefinition.inherited(TNTEntity::new, entityBase) .type(EntityType.TNT) .heightAndWidth(0.98f) + .offset(0.49f) .addTranslator(MetadataType.INT, TNTEntity::setFuseLength) .build(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index fecd72f67..a3f16875d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -59,6 +59,9 @@ import java.util.*; @Getter @Setter public class Entity implements GeyserEntity { + + private static final boolean PRINT_ENTITY_SPAWN_DEBUG = Boolean.parseBoolean(System.getProperty("Geyser.PrintEntitySpawnDebug", "false")); + protected final GeyserSession session; protected int entityId; @@ -181,7 +184,7 @@ public class Entity implements GeyserEntity { flagsDirty = false; - if (session.getGeyser().getConfig().isDebugMode()) { + if (session.getGeyser().getConfig().isDebugMode() && PRINT_ENTITY_SPAWN_DEBUG) { EntityType type = definition.entityType(); String name = type != null ? type.name() : getClass().getSimpleName(); session.getGeyser().getLogger().debug("Spawned entity " + name + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")"); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ExpOrbEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ExpOrbEntity.java index 5a79a98b3..9f61bc961 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ExpOrbEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ExpOrbEntity.java @@ -27,11 +27,18 @@ package org.geysermc.geyser.entity.type; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; +import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.session.GeyserSession; +import java.util.UUID; + public class ExpOrbEntity extends Entity { + public ExpOrbEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition entityDefinition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + this(session, 1, entityId, geyserId, position); + } + public ExpOrbEntity(GeyserSession session, int amount, int entityId, long geyserId, Vector3f position) { super(session, entityId, geyserId, null, EntityDefinitions.EXPERIENCE_ORB, position, Vector3f.ZERO, 0, 0, 0); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java index dca36cda0..47d97b8f7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java @@ -39,7 +39,17 @@ public class TNTEntity extends Entity implements Tickable { private int currentTick; public TNTEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { - super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + super(session, entityId, geyserId, uuid, definition, position.add(0, definition.offset(), 0), motion, yaw, pitch, headYaw); + } + + @Override + public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, boolean isOnGround) { + super.moveRelative(relX, relY + definition.offset(), relZ, yaw, pitch, isOnGround); + } + + @Override + public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) { + super.moveAbsolute(position.add(Vector3f.from(0, definition.offset(), 0)), yaw, pitch, headYaw, isOnGround, teleported); } public void setFuseLength(IntEntityMetadata entityMetadata) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java index 25040063e..4c67b882f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java @@ -41,6 +41,7 @@ import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; +import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.packet.*; import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity; import org.geysermc.geyser.entity.EntityDefinitions; @@ -166,6 +167,31 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { session.sendUpstreamPacket(addPlayerPacket); } + @Override + public void despawnEntity() { + super.despawnEntity(); + + // Since we re-use player entities: Clear flags, held item, etc + this.resetMetadata(); + this.hand = ItemData.AIR; + this.offhand = ItemData.AIR; + this.boots = ItemData.AIR; + this.leggings = ItemData.AIR; + this.chestplate = ItemData.AIR; + this.helmet = ItemData.AIR; + } + + public void resetMetadata() { + // Reset all metadata to their default values + // This is used when a player respawns + this.flags.clear(); + this.initializeMetadata(); + + // Explicitly reset all metadata not handled by initializeMetadata + setParrot(null, true); + setParrot(null, false); + } + public void sendPlayer() { if (session.getEntityCache().getPlayerEntity(uuid) == null) return; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java index e10adb134..533ca3c59 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java @@ -264,19 +264,13 @@ public class SessionPlayerEntity extends PlayerEntity { super.setAbsorptionHearts(entityMetadata); } + @Override public void resetMetadata() { - // Reset all metadata to their default values - // This is used when a player respawns - this.flags.clear(); - this.initializeMetadata(); + super.resetMetadata(); // Reset air this.resetAir(); - // Explicitly reset all metadata not handled by initializeMetadata - setParrot(null, true); - setParrot(null, false); - // Absorption is metadata in java edition attributes.remove(GeyserAttributeType.ABSORPTION); UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); From 5ebb6ef0d66ca5871c8c42adb245a2a3f48113d2 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 17 May 2024 22:48:46 +0200 Subject: [PATCH 2/9] Fix: using curly brackets in custom Minecraft locale overrides --- .../geyser/text/MinecraftTranslationRegistry.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/text/MinecraftTranslationRegistry.java b/core/src/main/java/org/geysermc/geyser/text/MinecraftTranslationRegistry.java index b59b4db8e..67654360d 100644 --- a/core/src/main/java/org/geysermc/geyser/text/MinecraftTranslationRegistry.java +++ b/core/src/main/java/org/geysermc/geyser/text/MinecraftTranslationRegistry.java @@ -63,6 +63,13 @@ public class MinecraftTranslationRegistry extends TranslatableComponentRenderer< } } + // replace single quote instances which get lost in MessageFormat otherwise + localeString = localeString.replace("'", "''"); + + // Wrap all curly brackets with single quote inserts - fixes https://github.com/GeyserMC/Geyser/issues/4662 + localeString = localeString.replace("{", "'{") + .replace("}", "'}"); + // Replace the `%s` with numbered inserts `{0}` Pattern p = stringReplacement; Matcher m = p.matcher(localeString); @@ -83,8 +90,7 @@ public class MinecraftTranslationRegistry extends TranslatableComponentRenderer< } m.appendTail(sb); - // replace single quote instances which get lost in MessageFormat otherwise // Locale shouldn't need to be specific - dates for example will not be handled - return new MessageFormat(sb.toString().replace("'", "''"), Locale.ROOT); + return new MessageFormat(sb.toString(), Locale.ROOT); } } From 8b7703154ef7b7df82e42cd7ce62e0211b14b3d6 Mon Sep 17 00:00:00 2001 From: chris Date: Sat, 18 May 2024 21:13:00 +0200 Subject: [PATCH 3/9] Resolve issue when trying to transfer a Geyser player (#4673) --- .../main/java/org/geysermc/geyser/session/GeyserSession.java | 3 +++ gradle/libs.versions.toml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 617087f71..2b7ec0a97 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -896,6 +896,9 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { this.downstream.getSession().setFlag(BuiltinFlags.ATTEMPT_SRV_RESOLVE, resolveSrv); } + // Disable automatic creation of a new TcpClientSession when transferring - we don't use that functionality. + this.downstream.getSession().setFlag(MinecraftConstants.FOLLOW_TRANSFERS, false); + if (geyser.getConfig().getRemote().isUseProxyProtocol()) { downstream.setFlag(BuiltinFlags.ENABLE_CLIENT_PROXY_PROTOCOL, true); downstream.setFlag(BuiltinFlags.CLIENT_PROXIED_ADDRESS, upstream.getAddress()); diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 65a5e3a52..dee170705 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "e5b0bcc" -mcprotocollib = "42ea4a4" # Revert from jitpack after release +mcprotocollib = "a1b559d" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From a780eeaae8d7a13c2c198a1880c14f0a704f5fb7 Mon Sep 17 00:00:00 2001 From: gecko10000 <60494179+gecko10000@users.noreply.github.com> Date: Mon, 20 May 2024 10:52:41 -0700 Subject: [PATCH 4/9] Open advancement tab regardless of currently open tab (#4665) --- .../geyser/session/cache/AdvancementsCache.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java index da3c83ed4..6769b4330 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java @@ -91,15 +91,13 @@ public class AdvancementsCache { builder.validResultHandler((response) -> { String id = rootAdvancementIds.get(response.clickedButtonId()); if (!id.equals("")) { - if (id.equals(currentAdvancementCategoryId)) { - // The server thinks we are already on this tab - buildAndShowListForm(); - } else { - // Send a packet indicating that we intend to open this particular advancement window + if (!id.equals(currentAdvancementCategoryId)) { + // Send a packet indicating that we are opening this particular advancement window ServerboundSeenAdvancementsPacket packet = new ServerboundSeenAdvancementsPacket(id); session.sendDownstreamGamePacket(packet); - // Wait for a response there } + currentAdvancementCategoryId = id; + buildAndShowListForm(); } }); From db166ad8dec5cc23998eeb2480629c8ca5884a97 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 20 May 2024 21:26:01 -0400 Subject: [PATCH 5/9] Small optimizations and BlockStateValues reduction --- .../spigot/world/GeyserPistonListener.java | 3 +- .../manager/GeyserSpigotWorldManager.java | 3 +- .../erosion/GeyserboundPacketHandlerImpl.java | 3 +- .../geyser/level/block/BlockStateValues.java | 45 ++------------- .../geysermc/geyser/level/block/Blocks.java | 5 +- .../level/block/property/FrontAndTop.java | 55 +++++++++++++++++++ .../level/block/property/Properties.java | 2 +- .../geyser/registry/ListRegistry.java | 18 ++++++ .../loader/CollisionRegistryLoader.java | 3 +- .../populator/BlockRegistryPopulator.java | 11 +--- .../JigsawBlockBlockEntityTranslator.java | 4 +- .../java/level/JavaBlockEventTranslator.java | 10 ++-- 12 files changed, 97 insertions(+), 65 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/property/FrontAndTop.java diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java index 2a6dc7a81..963f5bac3 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java @@ -41,6 +41,7 @@ import org.bukkit.event.block.BlockPistonRetractEvent; import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.platform.spigot.world.manager.GeyserSpigotWorldManager; @@ -120,7 +121,7 @@ public class GeyserPistonListener implements Listener { int pistonBlockId = worldManager.getBlockNetworkId(event.getBlock()); // event.getDirection() is unreliable - Direction orientation = BlockStateValues.getPistonOrientation(pistonBlockId); + Direction orientation = BlockState.of(pistonBlockId).getValue(Properties.FACING); session.executeInEventLoop(() -> { PistonCache pistonCache = session.getPistonCache(); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java index a04c60126..f45b68675 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java @@ -42,7 +42,6 @@ import org.geysermc.erosion.bukkit.SchedulerUtils; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.level.GameRule; import org.geysermc.geyser.level.WorldManager; -import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; @@ -88,7 +87,7 @@ public class GeyserSpigotWorldManager extends WorldManager { Bukkit.getRegionScheduler().execute(this.plugin, block.getLocation(), () -> blockData.complete(block.getBlockData().getAsString())); return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(blockData.join(), org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID); } - return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(block.getBlockData().getAsString(), org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID); + return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(block.getBlockData().getAsString(), org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID); // TODO could just make this a BlockState lookup? } @Override diff --git a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java index 9894a4ba2..c8cbe384b 100644 --- a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java +++ b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java @@ -44,6 +44,7 @@ import org.geysermc.erosion.packet.backendbound.BackendboundInitializePacket; import org.geysermc.erosion.packet.backendbound.BackendboundPacket; import org.geysermc.erosion.packet.geyserbound.*; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.Direction; @@ -148,7 +149,7 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke @Override public void handlePistonEvent(GeyserboundPistonEventPacket packet) { - Direction orientation = BlockStateValues.getPistonOrientation(packet.getBlockId()); + Direction orientation = BlockState.of(packet.getBlockId()).getValue(Properties.FACING); Vector3i position = packet.getPos(); boolean isExtend = packet.isExtend(); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java index 8bc9cf1e2..d52c46e33 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java @@ -25,7 +25,10 @@ package org.geysermc.geyser.level.block; -import it.unimi.dsi.fastutil.ints.*; +import it.unimi.dsi.fastutil.ints.Int2IntMap; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.geysermc.geyser.level.block.property.Properties; @@ -36,16 +39,11 @@ import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; -import java.util.Locale; - /** * Used for block entities if the Java block state contains Bedrock block information. */ public final class BlockStateValues { - private static final IntSet HORIZONTAL_FACING_JIGSAWS = new IntOpenHashSet(); - private static final IntSet STICKY_PISTONS = new IntOpenHashSet(); private static final Object2IntMap PISTON_HEADS = new Object2IntOpenHashMap<>(); - private static final Int2ObjectMap PISTON_ORIENTATION = new Int2ObjectOpenHashMap<>(); private static final IntSet ALL_PISTON_HEADS = new IntOpenHashSet(); private static final Int2IntMap WATER_LEVEL = new Int2IntOpenHashMap(); @@ -61,10 +59,6 @@ public final class BlockStateValues { */ public static void storeBlockStateValues(String javaId, int javaBlockState) { if (javaId.contains("piston[")) { // minecraft:moving_piston, minecraft:sticky_piston, minecraft:piston - if (javaId.contains("sticky")) { - STICKY_PISTONS.add(javaBlockState); - } - PISTON_ORIENTATION.put(javaBlockState, getBlockDirection(javaId)); return; } else if (javaId.startsWith("minecraft:piston_head")) { ALL_PISTON_HEADS.add(javaBlockState); @@ -78,27 +72,7 @@ public final class BlockStateValues { String strLevel = javaId.substring(javaId.lastIndexOf("level=") + 6, javaId.length() - 1); int level = Integer.parseInt(strLevel); WATER_LEVEL.put(javaBlockState, level); - return; } - - if (javaId.startsWith("minecraft:jigsaw[orientation=")) { - String blockStateData = javaId.substring(javaId.indexOf("orientation=") + "orientation=".length(), javaId.lastIndexOf('_')); - Direction direction = Direction.valueOf(blockStateData.toUpperCase(Locale.ROOT)); - if (direction.isHorizontal()) { - HORIZONTAL_FACING_JIGSAWS.add(javaBlockState); - } - } - } - - /** - * @return a set of all forward-facing jigsaws, to use as a fallback if NBT is missing. - */ - public static IntSet getHorizontalFacingJigsaws() { - return HORIZONTAL_FACING_JIGSAWS; - } - - public static boolean isStickyPiston(int blockState) { - return STICKY_PISTONS.contains(blockState); } public static boolean isPistonHead(int state) { @@ -116,17 +90,6 @@ public final class BlockStateValues { return PISTON_HEADS.getOrDefault(direction, Block.JAVA_AIR_ID); } - /** - * This is used in GeyserPistonEvents.java and accepts minecraft:piston, - * minecraft:sticky_piston, and minecraft:moving_piston. - * - * @param state The block state of the piston base - * @return The direction in which the piston faces - */ - public static Direction getPistonOrientation(int state) { - return PISTON_ORIENTATION.get(state); - } - /** * Checks if a block sticks to other blocks * (Slime and honey blocks) diff --git a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java index 91f02d65e..283ca2503 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.level.block; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.level.block.property.ChestType; +import org.geysermc.geyser.level.block.property.FrontAndTop; import org.geysermc.geyser.level.block.type.*; import org.geysermc.geyser.level.physics.Axis; import org.geysermc.geyser.level.physics.Direction; @@ -2169,7 +2170,7 @@ public final class Blocks { public static final Block STRUCTURE_BLOCK = register(new Block("structure_block", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) .enumState(STRUCTUREBLOCK_MODE, "save", "load", "corner", "data"))); public static final Block JIGSAW = register(new Block("jigsaw", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) - .enumState(ORIENTATION, "down_east", "down_north", "down_south", "down_west", "up_east", "up_north", "up_south", "up_west", "west_up", "east_up", "north_up", "south_up"))); + .enumState(ORIENTATION, FrontAndTop.VALUES))); public static final Block COMPOSTER = register(new Block("composter", builder().destroyTime(0.6f) .intState(LEVEL_COMPOSTER, 0, 8))); public static final Block TARGET = register(new Block("target", builder().destroyTime(0.5f) @@ -2799,7 +2800,7 @@ public final class Blocks { .booleanState(WATERLOGGED))); public static final Block CRAFTER = register(new Block("crafter", builder().setBlockEntity().destroyTime(1.5f) .booleanState(CRAFTING) - .enumState(ORIENTATION, "down_east", "down_north", "down_south", "down_west", "up_east", "up_north", "up_south", "up_west", "west_up", "east_up", "north_up", "south_up") + .enumState(ORIENTATION, FrontAndTop.VALUES) .booleanState(TRIGGERED))); public static final Block TRIAL_SPAWNER = register(new Block("trial_spawner", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(50.0f) .booleanState(OMINOUS) diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/FrontAndTop.java b/core/src/main/java/org/geysermc/geyser/level/block/property/FrontAndTop.java new file mode 100644 index 000000000..e674ac424 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/FrontAndTop.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.property; + +import org.geysermc.geyser.level.physics.Direction; + +public enum FrontAndTop { + DOWN_EAST(Direction.DOWN), + DOWN_NORTH(Direction.DOWN), + DOWN_SOUTH(Direction.DOWN), + DOWN_WEST(Direction.DOWN), + UP_EAST(Direction.UP), + UP_NORTH(Direction.UP), + UP_SOUTH(Direction.UP), + UP_WEST(Direction.UP), + WEST_UP(Direction.WEST), + EAST_UP(Direction.EAST), + NORTH_UP(Direction.NORTH), + SOUTH_UP(Direction.SOUTH); + + private final boolean horizontal; + + FrontAndTop(Direction front) { + this.horizontal = front.isHorizontal(); + } + + public boolean isHorizontal() { + return horizontal; + } + + public static final FrontAndTop[] VALUES = values(); +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java b/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java index 339d82f96..7df09003d 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java @@ -74,7 +74,7 @@ public final class Properties { public static final Property FACING_HOPPER = Property.create("facing"); public static final Property HORIZONTAL_FACING = Property.create("facing"); public static final Property FLOWER_AMOUNT = Property.create("flower_amount"); - public static final Property ORIENTATION = Property.create("orientation"); + public static final Property ORIENTATION = Property.create("orientation"); public static final Property ATTACH_FACE = Property.create("face"); public static final Property BELL_ATTACHMENT = Property.create("attachment"); public static final Property EAST_WALL = Property.create("east"); diff --git a/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java b/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java index d13c47ba8..34a78c370 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java +++ b/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java @@ -28,10 +28,13 @@ package org.geysermc.geyser.registry; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.registry.loader.RegistryLoader; +import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; public class ListRegistry extends Registry> { + private boolean frozen = false; + /** * Creates a new instance of this class with the given input and * {@link RegistryLoader}. The input specified is what the registry @@ -85,9 +88,24 @@ public class ListRegistry extends Registry> { * @return a new value into this registry with the given index. */ public M register(int index, M value) { + if (this.frozen) { + throw new IllegalStateException("Registry should not be modified after frozen!"); + } return this.mappings.set(index, value); } + /** + * Mark this registry as unsuitable for new additions. The backing list will then be optimized for storage. + */ + public void freeze() { + if (!this.frozen) { + this.frozen = true; + if (this.mappings instanceof ArrayList arrayList) { + arrayList.trimToSize(); + } + } + } + /** * Creates a new array registry with the given {@link RegistryLoader}. The * input type is not specified here, meaning the loader return type is either diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java index 2cd7f82d6..bd98ae0a5 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java @@ -77,7 +77,7 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader blockStates = BlockRegistries.BLOCK_STATES.get(); - List collisions = new ObjectArrayList<>(blockStates.size()); + var collisions = new ObjectArrayList(blockStates.size()); // Map of unique collisions to its instance Map collisionInstances = new Object2ObjectOpenHashMap<>(); @@ -102,6 +102,7 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader { - int blockId = session.getGeyser().getWorldManager().getBlockAt(session, position); - boolean sticky = BlockStateValues.isStickyPiston(blockId); + BlockState state = session.getGeyser().getWorldManager().blockAt(session, position); + boolean sticky = state.is(Blocks.STICKY_PISTON); boolean extended = action != PistonValueType.PUSHING; return new PistonBlockEntity(session, pos, direction, sticky, extended); }); From 0094fa1418e313361b94bc2e13010a9a84f20ab7 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 21 May 2024 14:25:57 -0400 Subject: [PATCH 6/9] BlockState values can now be switched at runtime E.G. Blocks.PISTON_HEAD.defaultBlockState().withValue(FACING, Direction.SOUTH) Some of the inspiration may be thanks to FerriteCore, at least with the shared property keys idea, so thank you to them. --- .../entity/type/FurnaceMinecartEntity.java | 7 +- .../entity/type/SpawnerMinecartEntity.java | 4 +- .../holder/BlockInventoryHolder.java | 33 +- .../geyser/level/block/BlockStateValues.java | 75 +- .../geysermc/geyser/level/block/Blocks.java | 1052 ++++++++--------- .../block/property/BasicEnumProperty.java | 63 + .../level/block/property/BooleanProperty.java | 46 + .../level/block/property/EnumProperty.java | 59 + .../level/block/property/IntegerProperty.java | 59 + .../level/block/property/Properties.java | 228 ++-- .../geyser/level/block/property/Property.java | 12 +- .../geyser/level/block/type/Block.java | 50 +- .../geyser/level/block/type/BlockState.java | 115 +- .../geyser/level/block/type/FurnaceBlock.java | 21 +- .../geyser/level/block/type/HoneyBlock.java | 13 - .../geyser/level/block/type/SpawnerBlock.java | 13 - .../geyser/level/block/type/WaterBlock.java | 9 - .../level/physics/CollisionManager.java | 6 +- .../populator/BlockRegistryPopulator.java | 13 - .../geyser/registry/type/BlockMappings.java | 4 + .../AbstractBlockInventoryTranslator.java | 15 +- .../inventory/AnvilInventoryTranslator.java | 2 +- .../inventory/BeaconInventoryTranslator.java | 11 +- .../inventory/BrewingInventoryTranslator.java | 7 +- .../CartographyInventoryTranslator.java | 3 +- .../inventory/CrafterInventoryTranslator.java | 3 +- .../CraftingInventoryTranslator.java | 3 +- .../EnchantingInventoryTranslator.java | 3 +- .../Generic3X3InventoryTranslator.java | 2 +- .../GrindstoneInventoryTranslator.java | 3 +- .../inventory/HopperInventoryTranslator.java | 3 +- .../inventory/LecternInventoryTranslator.java | 3 +- .../inventory/LoomInventoryTranslator.java | 3 +- .../inventory/OldSmithingTableTranslator.java | 3 +- .../inventory/ShulkerInventoryTranslator.java | 10 +- .../SmithingInventoryTranslator.java | 3 +- .../StonecutterInventoryTranslator.java | 3 +- .../chest/DoubleChestInventoryTranslator.java | 12 +- .../chest/SingleChestInventoryTranslator.java | 11 +- .../AbstractFurnaceInventoryTranslator.java | 6 +- .../BlastFurnaceInventoryTranslator.java | 3 +- .../furnace/FurnaceInventoryTranslator.java | 3 +- .../furnace/SmokerInventoryTranslator.java | 3 +- .../level/block/entity/PistonBlockEntity.java | 41 +- ...BedrockInventoryTransactionTranslator.java | 8 +- .../protocol/java/JavaCommandsTranslator.java | 9 +- gradle/libs.versions.toml | 3 +- 47 files changed, 1160 insertions(+), 901 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/property/BasicEnumProperty.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/property/BooleanProperty.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/property/EnumProperty.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/property/IntegerProperty.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java index 0fc5627ed..e33e6d7b6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java @@ -28,7 +28,9 @@ package org.geysermc.geyser.entity.type; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.level.block.type.FurnaceBlock; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; @@ -51,7 +53,8 @@ public class FurnaceMinecartEntity extends DefaultBlockMinecartEntity { @Override public void updateDefaultBlockMetadata() { - dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(FurnaceBlock.state(hasFuel))); + BlockState furnace = Blocks.FURNACE.defaultBlockState().withValue(Properties.LIT, hasFuel); + dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(furnace)); dirtyMetadata.put(EntityDataTypes.DISPLAY_OFFSET, 6); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/SpawnerMinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/SpawnerMinecartEntity.java index 65dfb800b..4d69c8a1e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/SpawnerMinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/SpawnerMinecartEntity.java @@ -28,7 +28,7 @@ package org.geysermc.geyser.entity.type; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.level.block.type.SpawnerBlock; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import java.util.UUID; @@ -41,7 +41,7 @@ public class SpawnerMinecartEntity extends DefaultBlockMinecartEntity { @Override public void updateDefaultBlockMetadata() { - dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(SpawnerBlock.state())); + dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(Blocks.SPAWNER.defaultBlockState())); dirtyMetadata.put(EntityDataTypes.DISPLAY_OFFSET, 6); } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java b/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java index 0a51d43ef..9c8e5de15 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java @@ -41,7 +41,6 @@ import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.InventoryTranslator; -import org.geysermc.geyser.util.BlockUtils; import org.geysermc.geyser.util.InventoryUtils; import java.util.Collections; @@ -56,22 +55,24 @@ public class BlockInventoryHolder extends InventoryHolder { /** * The default Java block ID to translate as a fake block */ - private final int defaultJavaBlockState; + private final BlockState defaultJavaBlockState; private final ContainerType containerType; - private final Set validBlocks; + private final Set validBlocks; - public BlockInventoryHolder(String javaBlockIdentifier, ContainerType containerType, Block... validBlocks) { - this.defaultJavaBlockState = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt(javaBlockIdentifier); + public BlockInventoryHolder(Block defaultJavaBlock, ContainerType containerType, Block... validBlocks) { + this(defaultJavaBlock.defaultBlockState(), containerType, validBlocks); + } + + public BlockInventoryHolder(BlockState defaultJavaBlockState, ContainerType containerType, Block... validBlocks) { + this.defaultJavaBlockState = defaultJavaBlockState; this.containerType = containerType; if (validBlocks != null) { - Set validBlocksTemp = new HashSet<>(validBlocks.length + 1); - for (Block block : validBlocks) { - validBlocksTemp.add(block.javaIdentifier().toString()); - } - validBlocksTemp.add(BlockUtils.getCleanIdentifier(javaBlockIdentifier)); + Set validBlocksTemp = new HashSet<>(validBlocks.length + 1); + Collections.addAll(validBlocksTemp, validBlocks); + validBlocksTemp.add(defaultJavaBlockState.block()); this.validBlocks = Set.copyOf(validBlocksTemp); } else { - this.validBlocks = Collections.singleton(BlockUtils.getCleanIdentifier(javaBlockIdentifier)); + this.validBlocks = Collections.singleton(defaultJavaBlockState.block()); } } @@ -85,9 +86,7 @@ public class BlockInventoryHolder extends InventoryHolder { // and the bedrock block is vanilla BlockState state = session.getGeyser().getWorldManager().blockAt(session, session.getLastInteractionBlockPosition()); if (!BlockRegistries.CUSTOM_BLOCK_STATE_OVERRIDES.get().containsKey(state.javaId())) { - // TODO TODO TODO - String[] javaBlockString = state.toString().split("\\["); - if (isValidBlock(javaBlockString)) { + if (isValidBlock(state)) { // We can safely use this block inventory.setHolderPosition(session.getLastInteractionBlockPosition()); ((Container) inventory).setUsingRealBlock(true, state.block()); @@ -111,7 +110,7 @@ public class BlockInventoryHolder extends InventoryHolder { session.sendUpstreamPacket(blockPacket); inventory.setHolderPosition(position); - setCustomName(session, position, inventory, BlockState.of(defaultJavaBlockState)); + setCustomName(session, position, inventory, defaultJavaBlockState); return true; } @@ -129,8 +128,8 @@ public class BlockInventoryHolder extends InventoryHolder { /** * @return true if this Java block ID can be used for player inventory. */ - protected boolean isValidBlock(String[] javaBlockString) { - return this.validBlocks.contains(javaBlockString[0]); + protected boolean isValidBlock(BlockState blockState) { + return this.validBlocks.contains(blockState.block()); } protected void setCustomName(GeyserSession session, Vector3i position, Inventory inventory, BlockState javaBlockState) { diff --git a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java index d52c46e33..01e95fc7a 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java @@ -25,17 +25,10 @@ package org.geysermc.geyser.level.block; -import it.unimi.dsi.fastutil.ints.Int2IntMap; -import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; -import it.unimi.dsi.fastutil.ints.IntOpenHashSet; -import it.unimi.dsi.fastutil.ints.IntSet; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.block.type.PistonBlock; -import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; @@ -43,53 +36,8 @@ import org.geysermc.geyser.registry.BlockRegistries; * Used for block entities if the Java block state contains Bedrock block information. */ public final class BlockStateValues { - private static final Object2IntMap PISTON_HEADS = new Object2IntOpenHashMap<>(); - private static final IntSet ALL_PISTON_HEADS = new IntOpenHashSet(); - private static final Int2IntMap WATER_LEVEL = new Int2IntOpenHashMap(); - - public static int JAVA_WATER_ID; - public static final int NUM_WATER_LEVELS = 9; - /** - * Determines if the block state contains Bedrock block information - * - * @param javaId The Java Identifier of the block - * @param javaBlockState the Java Block State of the block - */ - public static void storeBlockStateValues(String javaId, int javaBlockState) { - if (javaId.contains("piston[")) { // minecraft:moving_piston, minecraft:sticky_piston, minecraft:piston - return; - } else if (javaId.startsWith("minecraft:piston_head")) { - ALL_PISTON_HEADS.add(javaBlockState); - if (javaId.contains("short=false")) { - PISTON_HEADS.put(getBlockDirection(javaId), javaBlockState); - } - return; - } - - if (javaId.startsWith("minecraft:water") && !javaId.contains("cauldron")) { - String strLevel = javaId.substring(javaId.lastIndexOf("level=") + 6, javaId.length() - 1); - int level = Integer.parseInt(strLevel); - WATER_LEVEL.put(javaBlockState, level); - } - } - - public static boolean isPistonHead(int state) { - return ALL_PISTON_HEADS.contains(state); - } - - /** - * Get the Java Block State for a piston head for a specific direction - * This is used in PistonBlockEntity to get the BlockCollision for the piston head. - * - * @param direction Direction the piston head points in - * @return Block state for the piston head - */ - public static int getPistonHead(Direction direction) { - return PISTON_HEADS.getOrDefault(direction, Block.JAVA_AIR_ID); - } - /** * Checks if a block sticks to other blocks * (Slime and honey blocks) @@ -158,7 +106,11 @@ public final class BlockStateValues { * @return The water level or -1 if the block isn't water */ public static int getWaterLevel(int state) { - return WATER_LEVEL.getOrDefault(state, -1); + BlockState blockState = BlockState.of(state); + if (!blockState.is(Blocks.WATER)) { + return -1; + } + return blockState.getValue(Properties.LEVEL); } /** @@ -206,23 +158,6 @@ public final class BlockStateValues { return 0.6f; } - private static Direction getBlockDirection(String javaId) { - if (javaId.contains("down")) { - return Direction.DOWN; - } else if (javaId.contains("up")) { - return Direction.UP; - } else if (javaId.contains("south")) { - return Direction.SOUTH; - } else if (javaId.contains("west")) { - return Direction.WEST; - } else if (javaId.contains("north")) { - return Direction.NORTH; - } else if (javaId.contains("east")) { - return Direction.EAST; - } - throw new IllegalStateException(); - } - private BlockStateValues() { } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java index 283ca2503..fa605c079 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java @@ -65,36 +65,36 @@ public final class Blocks { public static final Block BAMBOO_PLANKS = register(new Block("bamboo_planks", builder().destroyTime(2.0f))); public static final Block BAMBOO_MOSAIC = register(new Block("bamboo_mosaic", builder().destroyTime(2.0f))); public static final Block OAK_SAPLING = register(new Block("oak_sapling", builder().pushReaction(PistonBehavior.DESTROY) - .intState(STAGE, 0, 1))); + .intState(STAGE))); public static final Block SPRUCE_SAPLING = register(new Block("spruce_sapling", builder().pushReaction(PistonBehavior.DESTROY) - .intState(STAGE, 0, 1))); + .intState(STAGE))); public static final Block BIRCH_SAPLING = register(new Block("birch_sapling", builder().pushReaction(PistonBehavior.DESTROY) - .intState(STAGE, 0, 1))); + .intState(STAGE))); public static final Block JUNGLE_SAPLING = register(new Block("jungle_sapling", builder().pushReaction(PistonBehavior.DESTROY) - .intState(STAGE, 0, 1))); + .intState(STAGE))); public static final Block ACACIA_SAPLING = register(new Block("acacia_sapling", builder().pushReaction(PistonBehavior.DESTROY) - .intState(STAGE, 0, 1))); + .intState(STAGE))); public static final Block CHERRY_SAPLING = register(new Block("cherry_sapling", builder().pushReaction(PistonBehavior.DESTROY) - .intState(STAGE, 0, 1))); + .intState(STAGE))); public static final Block DARK_OAK_SAPLING = register(new Block("dark_oak_sapling", builder().pushReaction(PistonBehavior.DESTROY) - .intState(STAGE, 0, 1))); + .intState(STAGE))); public static final Block MANGROVE_PROPAGULE = register(new Block("mangrove_propagule", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_4, 0, 4) + .intState(AGE_4) .booleanState(HANGING) - .intState(STAGE, 0, 1) + .intState(STAGE) .booleanState(WATERLOGGED))); public static final Block BEDROCK = register(new Block("bedrock", builder().destroyTime(-1.0f))); public static final Block WATER = register(new WaterBlock("water", builder().destroyTime(100.0f).pushReaction(PistonBehavior.DESTROY) - .intState(LEVEL, 0, 15))); + .intState(LEVEL))); public static final Block LAVA = register(new Block("lava", builder().destroyTime(100.0f).pushReaction(PistonBehavior.DESTROY) - .intState(LEVEL, 0, 15))); + .intState(LEVEL))); public static final Block SAND = register(new Block("sand", builder().destroyTime(0.5f))); public static final Block SUSPICIOUS_SAND = register(new Block("suspicious_sand", builder().setBlockEntity().destroyTime(0.25f).pushReaction(PistonBehavior.DESTROY) - .intState(DUSTED, 0, 3))); + .intState(DUSTED))); public static final Block RED_SAND = register(new Block("red_sand", builder().destroyTime(0.5f))); public static final Block GRAVEL = register(new Block("gravel", builder().destroyTime(0.6f))); public static final Block SUSPICIOUS_GRAVEL = register(new Block("suspicious_gravel", builder().setBlockEntity().destroyTime(0.25f).pushReaction(PistonBehavior.DESTROY) - .intState(DUSTED, 0, 3))); + .intState(DUSTED))); public static final Block GOLD_ORE = register(new Block("gold_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block DEEPSLATE_GOLD_ORE = register(new Block("deepslate_gold_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); public static final Block IRON_ORE = register(new Block("iron_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); @@ -175,43 +175,43 @@ public final class Blocks { public static final Block STRIPPED_MANGROVE_WOOD = register(new Block("stripped_mangrove_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); public static final Block OAK_LEAVES = register(new Block("oak_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block SPRUCE_LEAVES = register(new Block("spruce_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block BIRCH_LEAVES = register(new Block("birch_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block JUNGLE_LEAVES = register(new Block("jungle_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block ACACIA_LEAVES = register(new Block("acacia_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block CHERRY_LEAVES = register(new Block("cherry_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block DARK_OAK_LEAVES = register(new Block("dark_oak_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block MANGROVE_LEAVES = register(new Block("mangrove_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block AZALEA_LEAVES = register(new Block("azalea_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block FLOWERING_AZALEA_LEAVES = register(new Block("flowering_azalea_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block SPONGE = register(new Block("sponge", builder().destroyTime(0.6f))); @@ -227,80 +227,80 @@ public final class Blocks { public static final Block CHISELED_SANDSTONE = register(new Block("chiseled_sandstone", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); public static final Block CUT_SANDSTONE = register(new Block("cut_sandstone", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); public static final Block NOTE_BLOCK = register(new Block("note_block", builder().destroyTime(0.8f) - .enumState(NOTEBLOCK_INSTRUMENT, "harp", "basedrum", "snare", "hat", "bass", "flute", "bell", "guitar", "chime", "xylophone", "iron_xylophone", "cow_bell", "didgeridoo", "bit", "banjo", "pling", "zombie", "skeleton", "creeper", "dragon", "wither_skeleton", "piglin", "custom_head") - .intState(NOTE, 0, 24) + .enumState(NOTEBLOCK_INSTRUMENT) + .intState(NOTE) .booleanState(POWERED))); public static final Block WHITE_BED = register(new BedBlock("white_bed", 0, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block ORANGE_BED = register(new BedBlock("orange_bed", 1, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block MAGENTA_BED = register(new BedBlock("magenta_bed", 2, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block LIGHT_BLUE_BED = register(new BedBlock("light_blue_bed", 3, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block YELLOW_BED = register(new BedBlock("yellow_bed", 4, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block LIME_BED = register(new BedBlock("lime_bed", 5, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block PINK_BED = register(new BedBlock("pink_bed", 6, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block GRAY_BED = register(new BedBlock("gray_bed", 7, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block LIGHT_GRAY_BED = register(new BedBlock("light_gray_bed", 8, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block CYAN_BED = register(new BedBlock("cyan_bed", 9, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block PURPLE_BED = register(new BedBlock("purple_bed", 10, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block BLUE_BED = register(new BedBlock("blue_bed", 11, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block BROWN_BED = register(new BedBlock("brown_bed", 12, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block GREEN_BED = register(new BedBlock("green_bed", 13, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block RED_BED = register(new BedBlock("red_bed", 14, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block BLACK_BED = register(new BedBlock("black_bed", 15, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block POWERED_RAIL = register(new Block("powered_rail", builder().destroyTime(0.7f) .booleanState(POWERED) - .enumState(RAIL_SHAPE_STRAIGHT, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south") + .enumState(RAIL_SHAPE_STRAIGHT) .booleanState(WATERLOGGED))); public static final Block DETECTOR_RAIL = register(new Block("detector_rail", builder().destroyTime(0.7f) .booleanState(POWERED) - .enumState(RAIL_SHAPE_STRAIGHT, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south") + .enumState(RAIL_SHAPE_STRAIGHT) .booleanState(WATERLOGGED))); public static final Block STICKY_PISTON = register(new PistonBlock("sticky_piston", builder().destroyTime(1.5f).pushReaction(PistonBehavior.BLOCK) .booleanState(EXTENDED) @@ -311,14 +311,14 @@ public final class Blocks { public static final Block DEAD_BUSH = register(new Block("dead_bush", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block SEAGRASS = register(new Block("seagrass", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block TALL_SEAGRASS = register(new Block("tall_seagrass", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.SEAGRASS) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block PISTON = register(new PistonBlock("piston", builder().destroyTime(1.5f).pushReaction(PistonBehavior.BLOCK) .booleanState(EXTENDED) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); public static final Block PISTON_HEAD = register(new Block("piston_head", builder().destroyTime(1.5f).pushReaction(PistonBehavior.BLOCK) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(SHORT) - .enumState(PISTON_TYPE, "normal", "sticky"))); + .enumState(PISTON_TYPE))); public static final Block WHITE_WOOL = register(new Block("white_wool", builder().destroyTime(0.8f))); public static final Block ORANGE_WOOL = register(new Block("orange_wool", builder().destroyTime(0.8f))); public static final Block MAGENTA_WOOL = register(new Block("magenta_wool", builder().destroyTime(0.8f))); @@ -337,7 +337,7 @@ public final class Blocks { public static final Block BLACK_WOOL = register(new Block("black_wool", builder().destroyTime(0.8f))); public static final Block MOVING_PISTON = register(new MovingPistonBlock("moving_piston", builder().setBlockEntity().destroyTime(-1.0f).pushReaction(PistonBehavior.BLOCK) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) - .enumState(PISTON_TYPE, "normal", "sticky"))); + .enumState(PISTON_TYPE))); public static final Block DANDELION = register(new Block("dandelion", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block TORCHFLOWER = register(new Block("torchflower", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block POPPY = register(new Block("poppy", builder().pushReaction(PistonBehavior.DESTROY))); @@ -374,7 +374,7 @@ public final class Blocks { public static final Block WALL_TORCH = register(new Block("wall_torch", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block FIRE = register(new Block("fire", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_15, 0, 15) + .intState(AGE_15) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) @@ -384,73 +384,73 @@ public final class Blocks { public static final Block SPAWNER = register(new SpawnerBlock("spawner", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block OAK_STAIRS = register(new Block("oak_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block CHEST = register(new ChestBlock("chest", builder().setBlockEntity().destroyTime(2.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(CHEST_TYPE, ChestType.VALUES) .booleanState(WATERLOGGED))); public static final Block REDSTONE_WIRE = register(new Block("redstone_wire", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(EAST_REDSTONE, "up", "side", "none") - .enumState(NORTH_REDSTONE, "up", "side", "none") - .intState(POWER, 0, 15) - .enumState(SOUTH_REDSTONE, "up", "side", "none") - .enumState(WEST_REDSTONE, "up", "side", "none"))); + .enumState(EAST_REDSTONE) + .enumState(NORTH_REDSTONE) + .intState(POWER) + .enumState(SOUTH_REDSTONE) + .enumState(WEST_REDSTONE))); public static final Block DIAMOND_ORE = register(new Block("diamond_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block DEEPSLATE_DIAMOND_ORE = register(new Block("deepslate_diamond_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); public static final Block DIAMOND_BLOCK = register(new Block("diamond_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block CRAFTING_TABLE = register(new Block("crafting_table", builder().destroyTime(2.5f))); public static final Block WHEAT = register(new Block("wheat", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_7, 0, 7))); + .intState(AGE_7))); public static final Block FARMLAND = register(new Block("farmland", builder().destroyTime(0.6f) - .intState(MOISTURE, 0, 7))); + .intState(MOISTURE))); public static final Block FURNACE = register(new FurnaceBlock("furnace", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LIT))); public static final Block OAK_SIGN = register(new Block("oak_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block SPRUCE_SIGN = register(new Block("spruce_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block BIRCH_SIGN = register(new Block("birch_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block ACACIA_SIGN = register(new Block("acacia_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block CHERRY_SIGN = register(new Block("cherry_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block JUNGLE_SIGN = register(new Block("jungle_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block DARK_OAK_SIGN = register(new Block("dark_oak_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block MANGROVE_SIGN = register(new Block("mangrove_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block BAMBOO_SIGN = register(new Block("bamboo_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block OAK_DOOR = register(new DoorBlock("oak_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block LADDER = register(new Block("ladder", builder().destroyTime(0.4f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); public static final Block RAIL = register(new Block("rail", builder().destroyTime(0.7f) - .enumState(RAIL_SHAPE, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south", "south_east", "south_west", "north_west", "north_east") + .enumState(RAIL_SHAPE) .booleanState(WATERLOGGED))); public static final Block COBBLESTONE_STAIRS = register(new Block("cobblestone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block OAK_WALL_SIGN = register(new Block("oak_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) @@ -481,47 +481,47 @@ public final class Blocks { .booleanState(WATERLOGGED))); public static final Block OAK_HANGING_SIGN = register(new Block("oak_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block SPRUCE_HANGING_SIGN = register(new Block("spruce_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block BIRCH_HANGING_SIGN = register(new Block("birch_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block ACACIA_HANGING_SIGN = register(new Block("acacia_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block CHERRY_HANGING_SIGN = register(new Block("cherry_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block JUNGLE_HANGING_SIGN = register(new Block("jungle_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block DARK_OAK_HANGING_SIGN = register(new Block("dark_oak_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block CRIMSON_HANGING_SIGN = register(new Block("crimson_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block WARPED_HANGING_SIGN = register(new Block("warped_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block MANGROVE_HANGING_SIGN = register(new Block("mangrove_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block BAMBOO_HANGING_SIGN = register(new Block("bamboo_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block OAK_WALL_HANGING_SIGN = register(new Block("oak_wall_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) @@ -557,15 +557,15 @@ public final class Blocks { .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); public static final Block LEVER = register(new Block("lever", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block STONE_PRESSURE_PLATE = register(new Block("stone_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); public static final Block IRON_DOOR = register(new DoorBlock("iron_door", builder().requiresCorrectToolForDrops().destroyTime(5.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block OAK_PRESSURE_PLATE = register(new Block("oak_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) @@ -596,18 +596,18 @@ public final class Blocks { .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LIT))); public static final Block STONE_BUTTON = register(new Block("stone_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block SNOW = register(new Block("snow", builder().requiresCorrectToolForDrops().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(LAYERS, 1, 8))); + .intState(LAYERS))); public static final Block ICE = register(new Block("ice", builder().destroyTime(0.5f))); public static final Block SNOW_BLOCK = register(new Block("snow_block", builder().requiresCorrectToolForDrops().destroyTime(0.2f))); public static final Block CACTUS = register(new Block("cactus", builder().destroyTime(0.4f).pushReaction(PistonBehavior.DESTROY) - .intState(AGE_15, 0, 15))); + .intState(AGE_15))); public static final Block CLAY = register(new Block("clay", builder().destroyTime(0.6f))); public static final Block SUGAR_CANE = register(new Block("sugar_cane", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_15, 0, 15))); + .intState(AGE_15))); public static final Block JUKEBOX = register(new Block("jukebox", builder().setBlockEntity().destroyTime(2.0f) .booleanState(HAS_RECORD))); public static final Block OAK_FENCE = register(new Block("oak_fence", builder().destroyTime(2.0f) @@ -634,9 +634,9 @@ public final class Blocks { public static final Block JACK_O_LANTERN = register(new Block("jack_o_lantern", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block CAKE = register(new Block("cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .intState(BITES, 0, 6))); + .intState(BITES))); public static final Block REPEATER = register(new Block("repeater", builder().pushReaction(PistonBehavior.DESTROY) - .intState(DELAY, 1, 4) + .intState(DELAY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LOCKED) .booleanState(POWERED))); @@ -658,55 +658,55 @@ public final class Blocks { public static final Block BLACK_STAINED_GLASS = register(new Block("black_stained_glass", builder().destroyTime(0.3f))); public static final Block OAK_TRAPDOOR = register(new TrapDoorBlock("oak_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block SPRUCE_TRAPDOOR = register(new TrapDoorBlock("spruce_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block BIRCH_TRAPDOOR = register(new TrapDoorBlock("birch_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block JUNGLE_TRAPDOOR = register(new TrapDoorBlock("jungle_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block ACACIA_TRAPDOOR = register(new TrapDoorBlock("acacia_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block CHERRY_TRAPDOOR = register(new TrapDoorBlock("cherry_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block DARK_OAK_TRAPDOOR = register(new TrapDoorBlock("dark_oak_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block MANGROVE_TRAPDOOR = register(new TrapDoorBlock("mangrove_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block BAMBOO_TRAPDOOR = register(new TrapDoorBlock("bamboo_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); @@ -765,9 +765,9 @@ public final class Blocks { public static final Block ATTACHED_MELON_STEM = register(new Block("attached_melon_stem", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.MELON_SEEDS) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block PUMPKIN_STEM = register(new Block("pumpkin_stem", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_7, 0, 7))); + .intState(AGE_7))); public static final Block MELON_STEM = register(new Block("melon_stem", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_7, 0, 7))); + .intState(AGE_7))); public static final Block VINE = register(new Block("vine", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .booleanState(EAST) .booleanState(NORTH) @@ -789,18 +789,18 @@ public final class Blocks { .booleanState(POWERED))); public static final Block BRICK_STAIRS = register(new Block("brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block STONE_BRICK_STAIRS = register(new Block("stone_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block MUD_BRICK_STAIRS = register(new Block("mud_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block MYCELIUM = register(new Block("mycelium", builder().destroyTime(0.6f) .booleanState(SNOWY))); @@ -814,11 +814,11 @@ public final class Blocks { .booleanState(WEST))); public static final Block NETHER_BRICK_STAIRS = register(new Block("nether_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block NETHER_WART = register(new Block("nether_wart", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_3, 0, 3))); + .intState(AGE_3))); public static final Block ENCHANTING_TABLE = register(new Block("enchanting_table", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block BREWING_STAND = register(new Block("brewing_stand", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(0.5f) .booleanState(HAS_BOTTLE_0) @@ -826,10 +826,10 @@ public final class Blocks { .booleanState(HAS_BOTTLE_2))); public static final Block CAULDRON = register(new CauldronBlock("cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block WATER_CAULDRON = register(new CauldronBlock("water_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .intState(LEVEL_CAULDRON, 1, 3))); + .intState(LEVEL_CAULDRON))); public static final Block LAVA_CAULDRON = register(new CauldronBlock("lava_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block POWDER_SNOW_CAULDRON = register(new CauldronBlock("powder_snow_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .intState(LEVEL_CAULDRON, 1, 3))); + .intState(LEVEL_CAULDRON))); public static final Block END_PORTAL = register(new Block("end_portal", builder().setBlockEntity().destroyTime(-1.0f).pushReaction(PistonBehavior.BLOCK))); public static final Block END_PORTAL_FRAME = register(new Block("end_portal_frame", builder().destroyTime(-1.0f) .booleanState(EYE) @@ -839,12 +839,12 @@ public final class Blocks { public static final Block REDSTONE_LAMP = register(new Block("redstone_lamp", builder().destroyTime(0.3f) .booleanState(LIT))); public static final Block COCOA = register(new Block("cocoa", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(AGE_2, 0, 2) + .intState(AGE_2) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block SANDSTONE_STAIRS = register(new Block("sandstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(0.8f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block EMERALD_ORE = register(new Block("emerald_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block DEEPSLATE_EMERALD_ORE = register(new Block("deepslate_emerald_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); @@ -866,37 +866,37 @@ public final class Blocks { public static final Block EMERALD_BLOCK = register(new Block("emerald_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block SPRUCE_STAIRS = register(new Block("spruce_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block BIRCH_STAIRS = register(new Block("birch_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block JUNGLE_STAIRS = register(new Block("jungle_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block COMMAND_BLOCK = register(new Block("command_block", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) .booleanState(CONDITIONAL) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); public static final Block BEACON = register(new Block("beacon", builder().setBlockEntity().destroyTime(3.0f))); public static final Block COBBLESTONE_WALL = register(new Block("cobblestone_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block MOSSY_COBBLESTONE_WALL = register(new Block("mossy_cobblestone_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block FLOWER_POT = register(new FlowerPotBlock("flower_pot", AIR, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block POTTED_TORCHFLOWER = register(new FlowerPotBlock("potted_torchflower", TORCHFLOWER, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block POTTED_OAK_SAPLING = register(new FlowerPotBlock("potted_oak_sapling", OAK_SAPLING, builder().pushReaction(PistonBehavior.DESTROY))); @@ -926,84 +926,84 @@ public final class Blocks { public static final Block POTTED_DEAD_BUSH = register(new FlowerPotBlock("potted_dead_bush", DEAD_BUSH, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block POTTED_CACTUS = register(new FlowerPotBlock("potted_cactus", CACTUS, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block CARROTS = register(new Block("carrots", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_7, 0, 7))); + .intState(AGE_7))); public static final Block POTATOES = register(new Block("potatoes", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_7, 0, 7))); + .intState(AGE_7))); public static final Block OAK_BUTTON = register(new Block("oak_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block SPRUCE_BUTTON = register(new Block("spruce_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block BIRCH_BUTTON = register(new Block("birch_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block JUNGLE_BUTTON = register(new Block("jungle_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block ACACIA_BUTTON = register(new Block("acacia_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block CHERRY_BUTTON = register(new Block("cherry_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block DARK_OAK_BUTTON = register(new Block("dark_oak_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block MANGROVE_BUTTON = register(new Block("mangrove_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block BAMBOO_BUTTON = register(new Block("bamboo_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block SKELETON_SKULL = register(new SkullBlock("skeleton_skull", SkullBlock.Type.SKELETON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block SKELETON_WALL_SKULL = register(new WallSkullBlock("skeleton_wall_skull", SkullBlock.Type.SKELETON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block WITHER_SKELETON_SKULL = register(new SkullBlock("wither_skeleton_skull", SkullBlock.Type.WITHER_SKELETON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block WITHER_SKELETON_WALL_SKULL = register(new WallSkullBlock("wither_skeleton_wall_skull", SkullBlock.Type.WITHER_SKELETON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block ZOMBIE_HEAD = register(new SkullBlock("zombie_head", SkullBlock.Type.ZOMBIE, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block ZOMBIE_WALL_HEAD = register(new WallSkullBlock("zombie_wall_head", SkullBlock.Type.ZOMBIE, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block PLAYER_HEAD = register(new SkullBlock("player_head", SkullBlock.Type.PLAYER, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block PLAYER_WALL_HEAD = register(new WallSkullBlock("player_wall_head", SkullBlock.Type.PLAYER, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block CREEPER_HEAD = register(new SkullBlock("creeper_head", SkullBlock.Type.CREEPER, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block CREEPER_WALL_HEAD = register(new WallSkullBlock("creeper_wall_head", SkullBlock.Type.CREEPER, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block DRAGON_HEAD = register(new SkullBlock("dragon_head", SkullBlock.Type.DRAGON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block DRAGON_WALL_HEAD = register(new WallSkullBlock("dragon_wall_head", SkullBlock.Type.DRAGON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block PIGLIN_HEAD = register(new SkullBlock("piglin_head", SkullBlock.Type.PIGLIN, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block PIGLIN_WALL_HEAD = register(new WallSkullBlock("piglin_wall_head", SkullBlock.Type.PIGLIN, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); @@ -1018,16 +1018,16 @@ public final class Blocks { .enumState(CHEST_TYPE, ChestType.VALUES) .booleanState(WATERLOGGED))); public static final Block LIGHT_WEIGHTED_PRESSURE_PLATE = register(new Block("light_weighted_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .intState(POWER, 0, 15))); + .intState(POWER))); public static final Block HEAVY_WEIGHTED_PRESSURE_PLATE = register(new Block("heavy_weighted_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .intState(POWER, 0, 15))); + .intState(POWER))); public static final Block COMPARATOR = register(new Block("comparator", builder().setBlockEntity().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(MODE_COMPARATOR, "compare", "subtract") + .enumState(MODE_COMPARATOR) .booleanState(POWERED))); public static final Block DAYLIGHT_DETECTOR = register(new Block("daylight_detector", builder().setBlockEntity().destroyTime(0.2f) .booleanState(INVERTED) - .intState(POWER, 0, 15))); + .intState(POWER))); public static final Block REDSTONE_BLOCK = register(new Block("redstone_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block NETHER_QUARTZ_ORE = register(new Block("nether_quartz_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block HOPPER = register(new Block("hopper", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(3.0f) @@ -1039,12 +1039,12 @@ public final class Blocks { .enumState(AXIS, Axis.VALUES))); public static final Block QUARTZ_STAIRS = register(new Block("quartz_stairs", builder().requiresCorrectToolForDrops().destroyTime(0.8f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block ACTIVATOR_RAIL = register(new Block("activator_rail", builder().destroyTime(0.7f) .booleanState(POWERED) - .enumState(RAIL_SHAPE_STRAIGHT, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south") + .enumState(RAIL_SHAPE_STRAIGHT) .booleanState(WATERLOGGED))); public static final Block DROPPER = register(new Block("dropper", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) @@ -1163,43 +1163,43 @@ public final class Blocks { .booleanState(WEST))); public static final Block ACACIA_STAIRS = register(new Block("acacia_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block CHERRY_STAIRS = register(new Block("cherry_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block DARK_OAK_STAIRS = register(new Block("dark_oak_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block MANGROVE_STAIRS = register(new Block("mangrove_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block BAMBOO_STAIRS = register(new Block("bamboo_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block BAMBOO_MOSAIC_STAIRS = register(new Block("bamboo_mosaic_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block SLIME_BLOCK = register(new Block("slime_block", builder())); public static final Block BARRIER = register(new Block("barrier", builder().destroyTime(-1.0f).pushReaction(PistonBehavior.BLOCK) .booleanState(WATERLOGGED))); public static final Block LIGHT = register(new Block("light", builder().destroyTime(-1.0f) - .intState(LEVEL, 0, 15) + .intState(LEVEL) .booleanState(WATERLOGGED))); public static final Block IRON_TRAPDOOR = register(new TrapDoorBlock("iron_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(5.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); @@ -1208,27 +1208,27 @@ public final class Blocks { public static final Block DARK_PRISMARINE = register(new Block("dark_prismarine", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block PRISMARINE_STAIRS = register(new Block("prismarine_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block PRISMARINE_BRICK_STAIRS = register(new Block("prismarine_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block DARK_PRISMARINE_STAIRS = register(new Block("dark_prismarine_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block PRISMARINE_SLAB = register(new Block("prismarine_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block PRISMARINE_BRICK_SLAB = register(new Block("prismarine_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block DARK_PRISMARINE_SLAB = register(new Block("dark_prismarine_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SEA_LANTERN = register(new Block("sea_lantern", builder().destroyTime(0.3f))); public static final Block HAY_BLOCK = register(new Block("hay_block", builder().destroyTime(0.5f) @@ -1253,49 +1253,49 @@ public final class Blocks { public static final Block COAL_BLOCK = register(new Block("coal_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block PACKED_ICE = register(new Block("packed_ice", builder().destroyTime(0.5f))); public static final Block SUNFLOWER = register(new Block("sunflower", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block LILAC = register(new Block("lilac", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block ROSE_BUSH = register(new Block("rose_bush", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block PEONY = register(new Block("peony", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block TALL_GRASS = register(new Block("tall_grass", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block LARGE_FERN = register(new Block("large_fern", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block WHITE_BANNER = register(new BannerBlock("white_banner", 0, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block ORANGE_BANNER = register(new BannerBlock("orange_banner", 1, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block MAGENTA_BANNER = register(new BannerBlock("magenta_banner", 2, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block LIGHT_BLUE_BANNER = register(new BannerBlock("light_blue_banner", 3, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block YELLOW_BANNER = register(new BannerBlock("yellow_banner", 4, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block LIME_BANNER = register(new BannerBlock("lime_banner", 5, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block PINK_BANNER = register(new BannerBlock("pink_banner", 6, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block GRAY_BANNER = register(new BannerBlock("gray_banner", 7, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block LIGHT_GRAY_BANNER = register(new BannerBlock("light_gray_banner", 8, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block CYAN_BANNER = register(new BannerBlock("cyan_banner", 9, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block PURPLE_BANNER = register(new BannerBlock("purple_banner", 10, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block BLUE_BANNER = register(new BannerBlock("blue_banner", 11, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block BROWN_BANNER = register(new BannerBlock("brown_banner", 12, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block GREEN_BANNER = register(new BannerBlock("green_banner", 13, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block RED_BANNER = register(new BannerBlock("red_banner", 14, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block BLACK_BANNER = register(new BannerBlock("black_banner", 15, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block WHITE_WALL_BANNER = register(new BannerBlock("white_wall_banner", 0, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block ORANGE_WALL_BANNER = register(new BannerBlock("orange_wall_banner", 1, builder().setBlockEntity().destroyTime(1.0f) @@ -1333,80 +1333,80 @@ public final class Blocks { public static final Block CUT_RED_SANDSTONE = register(new Block("cut_red_sandstone", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); public static final Block RED_SANDSTONE_STAIRS = register(new Block("red_sandstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(0.8f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block OAK_SLAB = register(new Block("oak_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SPRUCE_SLAB = register(new Block("spruce_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block BIRCH_SLAB = register(new Block("birch_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block JUNGLE_SLAB = register(new Block("jungle_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block ACACIA_SLAB = register(new Block("acacia_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block CHERRY_SLAB = register(new Block("cherry_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block DARK_OAK_SLAB = register(new Block("dark_oak_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block MANGROVE_SLAB = register(new Block("mangrove_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block BAMBOO_SLAB = register(new Block("bamboo_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block BAMBOO_MOSAIC_SLAB = register(new Block("bamboo_mosaic_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block STONE_SLAB = register(new Block("stone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_STONE_SLAB = register(new Block("smooth_stone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SANDSTONE_SLAB = register(new Block("sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block CUT_SANDSTONE_SLAB = register(new Block("cut_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block PETRIFIED_OAK_SLAB = register(new Block("petrified_oak_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block COBBLESTONE_SLAB = register(new Block("cobblestone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block BRICK_SLAB = register(new Block("brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block STONE_BRICK_SLAB = register(new Block("stone_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block MUD_BRICK_SLAB = register(new Block("mud_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block NETHER_BRICK_SLAB = register(new Block("nether_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block QUARTZ_SLAB = register(new Block("quartz_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block RED_SANDSTONE_SLAB = register(new Block("red_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block CUT_RED_SANDSTONE_SLAB = register(new Block("cut_red_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block PURPUR_SLAB = register(new Block("purpur_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_STONE = register(new Block("smooth_stone", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block SMOOTH_SANDSTONE = register(new Block("smooth_sandstone", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); @@ -1502,50 +1502,50 @@ public final class Blocks { .booleanState(WEST))); public static final Block SPRUCE_DOOR = register(new DoorBlock("spruce_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block BIRCH_DOOR = register(new DoorBlock("birch_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block JUNGLE_DOOR = register(new DoorBlock("jungle_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block ACACIA_DOOR = register(new DoorBlock("acacia_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block CHERRY_DOOR = register(new DoorBlock("cherry_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block DARK_OAK_DOOR = register(new DoorBlock("dark_oak_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block MANGROVE_DOOR = register(new DoorBlock("mangrove_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block BAMBOO_DOOR = register(new DoorBlock("bamboo_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block END_ROD = register(new Block("end_rod", builder() @@ -1558,25 +1558,25 @@ public final class Blocks { .booleanState(UP) .booleanState(WEST))); public static final Block CHORUS_FLOWER = register(new Block("chorus_flower", builder().destroyTime(0.4f).pushReaction(PistonBehavior.DESTROY) - .intState(AGE_5, 0, 5))); + .intState(AGE_5))); public static final Block PURPUR_BLOCK = register(new Block("purpur_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block PURPUR_PILLAR = register(new Block("purpur_pillar", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(AXIS, Axis.VALUES))); public static final Block PURPUR_STAIRS = register(new Block("purpur_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block END_STONE_BRICKS = register(new Block("end_stone_bricks", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block TORCHFLOWER_CROP = register(new Block("torchflower_crop", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_1, 0, 1))); + .intState(AGE_1))); public static final Block PITCHER_CROP = register(new Block("pitcher_crop", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_4, 0, 4) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .intState(AGE_4) + .enumState(DOUBLE_BLOCK_HALF))); public static final Block PITCHER_PLANT = register(new Block("pitcher_plant", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block BEETROOTS = register(new Block("beetroots", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_3, 0, 3))); + .intState(AGE_3))); public static final Block DIRT_PATH = register(new Block("dirt_path", builder().destroyTime(0.65f))); public static final Block END_GATEWAY = register(new Block("end_gateway", builder().setBlockEntity().destroyTime(-1.0f).pushReaction(PistonBehavior.BLOCK))); public static final Block REPEATING_COMMAND_BLOCK = register(new Block("repeating_command_block", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) @@ -1586,7 +1586,7 @@ public final class Blocks { .booleanState(CONDITIONAL) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); public static final Block FROSTED_ICE = register(new Block("frosted_ice", builder().destroyTime(0.5f) - .intState(AGE_3, 0, 3))); + .intState(AGE_3))); public static final Block MAGMA_BLOCK = register(new Block("magma_block", builder().requiresCorrectToolForDrops().destroyTime(0.5f))); public static final Block NETHER_WART_BLOCK = register(new Block("nether_wart_block", builder().destroyTime(1.0f))); public static final Block RED_NETHER_BRICKS = register(new Block("red_nether_bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); @@ -1695,14 +1695,14 @@ public final class Blocks { public static final Block RED_CONCRETE_POWDER = register(new Block("red_concrete_powder", builder().destroyTime(0.5f))); public static final Block BLACK_CONCRETE_POWDER = register(new Block("black_concrete_powder", builder().destroyTime(0.5f))); public static final Block KELP = register(new Block("kelp", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_25, 0, 25))); + .intState(AGE_25))); public static final Block KELP_PLANT = register(new Block("kelp_plant", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.KELP))); public static final Block DRIED_KELP_BLOCK = register(new Block("dried_kelp_block", builder().destroyTime(0.5f))); public static final Block TURTLE_EGG = register(new Block("turtle_egg", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .intState(EGGS, 1, 4) - .intState(HATCH, 0, 2))); + .intState(EGGS) + .intState(HATCH))); public static final Block SNIFFER_EGG = register(new Block("sniffer_egg", builder().destroyTime(0.5f) - .intState(HATCH, 0, 2))); + .intState(HATCH))); public static final Block DEAD_TUBE_CORAL_BLOCK = register(new Block("dead_tube_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block DEAD_BRAIN_CORAL_BLOCK = register(new Block("dead_brain_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block DEAD_BUBBLE_CORAL_BLOCK = register(new Block("dead_bubble_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); @@ -1784,16 +1784,16 @@ public final class Blocks { .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); public static final Block SEA_PICKLE = register(new Block("sea_pickle", builder().pushReaction(PistonBehavior.DESTROY) - .intState(PICKLES, 1, 4) + .intState(PICKLES) .booleanState(WATERLOGGED))); public static final Block BLUE_ICE = register(new Block("blue_ice", builder().destroyTime(2.8f))); public static final Block CONDUIT = register(new Block("conduit", builder().setBlockEntity().destroyTime(3.0f) .booleanState(WATERLOGGED))); public static final Block BAMBOO_SAPLING = register(new Block("bamboo_sapling", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.BAMBOO))); public static final Block BAMBOO = register(new Block("bamboo", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) - .intState(AGE_1, 0, 1) - .enumState(BAMBOO_LEAVES, "none", "small", "large") - .intState(STAGE, 0, 1))); + .intState(AGE_1) + .enumState(BAMBOO_LEAVES) + .intState(STAGE))); public static final Block POTTED_BAMBOO = register(new FlowerPotBlock("potted_bamboo", BAMBOO, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block VOID_AIR = register(new Block("void_air", builder())); public static final Block CAVE_AIR = register(new Block("cave_air", builder())); @@ -1801,207 +1801,207 @@ public final class Blocks { .booleanState(DRAG))); public static final Block POLISHED_GRANITE_STAIRS = register(new Block("polished_granite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_RED_SANDSTONE_STAIRS = register(new Block("smooth_red_sandstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block MOSSY_STONE_BRICK_STAIRS = register(new Block("mossy_stone_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_DIORITE_STAIRS = register(new Block("polished_diorite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block MOSSY_COBBLESTONE_STAIRS = register(new Block("mossy_cobblestone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block END_STONE_BRICK_STAIRS = register(new Block("end_stone_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block STONE_STAIRS = register(new Block("stone_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_SANDSTONE_STAIRS = register(new Block("smooth_sandstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_QUARTZ_STAIRS = register(new Block("smooth_quartz_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block GRANITE_STAIRS = register(new Block("granite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block ANDESITE_STAIRS = register(new Block("andesite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block RED_NETHER_BRICK_STAIRS = register(new Block("red_nether_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_ANDESITE_STAIRS = register(new Block("polished_andesite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block DIORITE_STAIRS = register(new Block("diorite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_GRANITE_SLAB = register(new Block("polished_granite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_RED_SANDSTONE_SLAB = register(new Block("smooth_red_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block MOSSY_STONE_BRICK_SLAB = register(new Block("mossy_stone_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_DIORITE_SLAB = register(new Block("polished_diorite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block MOSSY_COBBLESTONE_SLAB = register(new Block("mossy_cobblestone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block END_STONE_BRICK_SLAB = register(new Block("end_stone_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_SANDSTONE_SLAB = register(new Block("smooth_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_QUARTZ_SLAB = register(new Block("smooth_quartz_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block GRANITE_SLAB = register(new Block("granite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block ANDESITE_SLAB = register(new Block("andesite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block RED_NETHER_BRICK_SLAB = register(new Block("red_nether_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_ANDESITE_SLAB = register(new Block("polished_andesite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block DIORITE_SLAB = register(new Block("diorite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block BRICK_WALL = register(new Block("brick_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block PRISMARINE_WALL = register(new Block("prismarine_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block RED_SANDSTONE_WALL = register(new Block("red_sandstone_wall", builder().requiresCorrectToolForDrops().destroyTime(0.8f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block MOSSY_STONE_BRICK_WALL = register(new Block("mossy_stone_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block GRANITE_WALL = register(new Block("granite_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block STONE_BRICK_WALL = register(new Block("stone_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block MUD_BRICK_WALL = register(new Block("mud_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block NETHER_BRICK_WALL = register(new Block("nether_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block ANDESITE_WALL = register(new Block("andesite_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block RED_NETHER_BRICK_WALL = register(new Block("red_nether_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block SANDSTONE_WALL = register(new Block("sandstone_wall", builder().requiresCorrectToolForDrops().destroyTime(0.8f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block END_STONE_BRICK_WALL = register(new Block("end_stone_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block DIORITE_WALL = register(new Block("diorite_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block SCAFFOLDING = register(new Block("scaffolding", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(BOTTOM) - .intState(STABILITY_DISTANCE, 0, 7) + .intState(STABILITY_DISTANCE) .booleanState(WATERLOGGED))); public static final Block LOOM = register(new Block("loom", builder().destroyTime(2.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); @@ -2017,7 +2017,7 @@ public final class Blocks { public static final Block CARTOGRAPHY_TABLE = register(new Block("cartography_table", builder().destroyTime(2.5f))); public static final Block FLETCHING_TABLE = register(new Block("fletching_table", builder().destroyTime(2.5f))); public static final Block GRINDSTONE = register(new Block("grindstone", builder().requiresCorrectToolForDrops().destroyTime(2.0f).pushReaction(PistonBehavior.BLOCK) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block LECTERN = register(new LecternBlock("lectern", builder().setBlockEntity().destroyTime(2.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) @@ -2027,7 +2027,7 @@ public final class Blocks { public static final Block STONECUTTER = register(new Block("stonecutter", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block BELL = register(new Block("bell", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f).pushReaction(PistonBehavior.DESTROY) - .enumState(BELL_ATTACHMENT, "floor", "ceiling", "single_wall", "double_wall") + .enumState(BELL_ATTACHMENT) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block LANTERN = register(new Block("lantern", builder().requiresCorrectToolForDrops().destroyTime(3.5f).pushReaction(PistonBehavior.DESTROY) @@ -2047,7 +2047,7 @@ public final class Blocks { .booleanState(SIGNAL_FIRE) .booleanState(WATERLOGGED))); public static final Block SWEET_BERRY_BUSH = register(new Block("sweet_berry_bush", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_3, 0, 3))); + .intState(AGE_3))); public static final Block WARPED_STEM = register(new Block("warped_stem", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); public static final Block STRIPPED_WARPED_STEM = register(new Block("stripped_warped_stem", builder().destroyTime(2.0f) @@ -2073,19 +2073,19 @@ public final class Blocks { public static final Block CRIMSON_FUNGUS = register(new Block("crimson_fungus", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block SHROOMLIGHT = register(new Block("shroomlight", builder().destroyTime(1.0f))); public static final Block WEEPING_VINES = register(new Block("weeping_vines", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_25, 0, 25))); + .intState(AGE_25))); public static final Block WEEPING_VINES_PLANT = register(new Block("weeping_vines_plant", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.WEEPING_VINES))); public static final Block TWISTING_VINES = register(new Block("twisting_vines", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_25, 0, 25))); + .intState(AGE_25))); public static final Block TWISTING_VINES_PLANT = register(new Block("twisting_vines_plant", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.TWISTING_VINES))); public static final Block CRIMSON_ROOTS = register(new Block("crimson_roots", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block CRIMSON_PLANKS = register(new Block("crimson_planks", builder().destroyTime(2.0f))); public static final Block WARPED_PLANKS = register(new Block("warped_planks", builder().destroyTime(2.0f))); public static final Block CRIMSON_SLAB = register(new Block("crimson_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block WARPED_SLAB = register(new Block("warped_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block CRIMSON_PRESSURE_PLATE = register(new Block("crimson_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); @@ -2105,13 +2105,13 @@ public final class Blocks { .booleanState(WEST))); public static final Block CRIMSON_TRAPDOOR = register(new TrapDoorBlock("crimson_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block WARPED_TRAPDOOR = register(new TrapDoorBlock("warped_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); @@ -2127,39 +2127,39 @@ public final class Blocks { .booleanState(POWERED))); public static final Block CRIMSON_STAIRS = register(new Block("crimson_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block WARPED_STAIRS = register(new Block("warped_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block CRIMSON_BUTTON = register(new Block("crimson_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block WARPED_BUTTON = register(new Block("warped_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block CRIMSON_DOOR = register(new DoorBlock("crimson_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block WARPED_DOOR = register(new DoorBlock("warped_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block CRIMSON_SIGN = register(new Block("crimson_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block WARPED_SIGN = register(new Block("warped_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block CRIMSON_WALL_SIGN = register(new Block("crimson_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) @@ -2168,26 +2168,26 @@ public final class Blocks { .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); public static final Block STRUCTURE_BLOCK = register(new Block("structure_block", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) - .enumState(STRUCTUREBLOCK_MODE, "save", "load", "corner", "data"))); + .enumState(STRUCTUREBLOCK_MODE))); public static final Block JIGSAW = register(new Block("jigsaw", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) .enumState(ORIENTATION, FrontAndTop.VALUES))); public static final Block COMPOSTER = register(new Block("composter", builder().destroyTime(0.6f) - .intState(LEVEL_COMPOSTER, 0, 8))); + .intState(LEVEL_COMPOSTER))); public static final Block TARGET = register(new Block("target", builder().destroyTime(0.5f) - .intState(POWER, 0, 15))); + .intState(POWER))); public static final Block BEE_NEST = register(new Block("bee_nest", builder().setBlockEntity().destroyTime(0.3f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .intState(LEVEL_HONEY, 0, 5))); + .intState(LEVEL_HONEY))); public static final Block BEEHIVE = register(new Block("beehive", builder().setBlockEntity().destroyTime(0.6f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .intState(LEVEL_HONEY, 0, 5))); + .intState(LEVEL_HONEY))); public static final Block HONEY_BLOCK = register(new HoneyBlock("honey_block", builder())); public static final Block HONEYCOMB_BLOCK = register(new Block("honeycomb_block", builder().destroyTime(0.6f))); public static final Block NETHERITE_BLOCK = register(new Block("netherite_block", builder().requiresCorrectToolForDrops().destroyTime(50.0f))); public static final Block ANCIENT_DEBRIS = register(new Block("ancient_debris", builder().requiresCorrectToolForDrops().destroyTime(30.0f))); public static final Block CRYING_OBSIDIAN = register(new Block("crying_obsidian", builder().requiresCorrectToolForDrops().destroyTime(50.0f))); public static final Block RESPAWN_ANCHOR = register(new Block("respawn_anchor", builder().requiresCorrectToolForDrops().destroyTime(50.0f) - .intState(RESPAWN_ANCHOR_CHARGES, 0, 4))); + .intState(RESPAWN_ANCHOR_CHARGES))); public static final Block POTTED_CRIMSON_FUNGUS = register(new FlowerPotBlock("potted_crimson_fungus", CRIMSON_FUNGUS, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block POTTED_WARPED_FUNGUS = register(new FlowerPotBlock("potted_warped_fungus", WARPED_FUNGUS, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block POTTED_CRIMSON_ROOTS = register(new FlowerPotBlock("potted_crimson_roots", CRIMSON_ROOTS, builder().pushReaction(PistonBehavior.DESTROY))); @@ -2196,129 +2196,129 @@ public final class Blocks { public static final Block BLACKSTONE = register(new Block("blackstone", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block BLACKSTONE_STAIRS = register(new Block("blackstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block BLACKSTONE_WALL = register(new Block("blackstone_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block BLACKSTONE_SLAB = register(new Block("blackstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_BLACKSTONE = register(new Block("polished_blackstone", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block POLISHED_BLACKSTONE_BRICKS = register(new Block("polished_blackstone_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block CRACKED_POLISHED_BLACKSTONE_BRICKS = register(new Block("cracked_polished_blackstone_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block CHISELED_POLISHED_BLACKSTONE = register(new Block("chiseled_polished_blackstone", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block POLISHED_BLACKSTONE_BRICK_SLAB = register(new Block("polished_blackstone_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_BLACKSTONE_BRICK_STAIRS = register(new Block("polished_blackstone_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_BLACKSTONE_BRICK_WALL = register(new Block("polished_blackstone_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block GILDED_BLACKSTONE = register(new Block("gilded_blackstone", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block POLISHED_BLACKSTONE_STAIRS = register(new Block("polished_blackstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_BLACKSTONE_SLAB = register(new Block("polished_blackstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_BLACKSTONE_PRESSURE_PLATE = register(new Block("polished_blackstone_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); public static final Block POLISHED_BLACKSTONE_BUTTON = register(new Block("polished_blackstone_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block POLISHED_BLACKSTONE_WALL = register(new Block("polished_blackstone_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block CHISELED_NETHER_BRICKS = register(new Block("chiseled_nether_bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block CRACKED_NETHER_BRICKS = register(new Block("cracked_nether_bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block QUARTZ_BRICKS = register(new Block("quartz_bricks", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); public static final Block CANDLE = register(new Block("candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block WHITE_CANDLE = register(new Block("white_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block ORANGE_CANDLE = register(new Block("orange_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block MAGENTA_CANDLE = register(new Block("magenta_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block LIGHT_BLUE_CANDLE = register(new Block("light_blue_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block YELLOW_CANDLE = register(new Block("yellow_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block LIME_CANDLE = register(new Block("lime_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block PINK_CANDLE = register(new Block("pink_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block GRAY_CANDLE = register(new Block("gray_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block LIGHT_GRAY_CANDLE = register(new Block("light_gray_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block CYAN_CANDLE = register(new Block("cyan_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block PURPLE_CANDLE = register(new Block("purple_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block BLUE_CANDLE = register(new Block("blue_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block BROWN_CANDLE = register(new Block("brown_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block GREEN_CANDLE = register(new Block("green_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block RED_CANDLE = register(new Block("red_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block BLACK_CANDLE = register(new Block("black_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block CANDLE_CAKE = register(new Block("candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) @@ -2371,65 +2371,65 @@ public final class Blocks { .booleanState(WATERLOGGED))); public static final Block TUFF = register(new Block("tuff", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block TUFF_SLAB = register(new Block("tuff_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block TUFF_STAIRS = register(new Block("tuff_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block TUFF_WALL = register(new Block("tuff_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block POLISHED_TUFF = register(new Block("polished_tuff", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block POLISHED_TUFF_SLAB = register(new Block("polished_tuff_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_TUFF_STAIRS = register(new Block("polished_tuff_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_TUFF_WALL = register(new Block("polished_tuff_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block CHISELED_TUFF = register(new Block("chiseled_tuff", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block TUFF_BRICKS = register(new Block("tuff_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block TUFF_BRICK_SLAB = register(new Block("tuff_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block TUFF_BRICK_STAIRS = register(new Block("tuff_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block TUFF_BRICK_WALL = register(new Block("tuff_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block CHISELED_TUFF_BRICKS = register(new Block("chiseled_tuff_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block CALCITE = register(new Block("calcite", builder().requiresCorrectToolForDrops().destroyTime(0.75f))); public static final Block TINTED_GLASS = register(new Block("tinted_glass", builder().destroyTime(0.3f))); public static final Block POWDER_SNOW = register(new Block("powder_snow", builder().destroyTime(0.25f))); public static final Block SCULK_SENSOR = register(new Block("sculk_sensor", builder().setBlockEntity().destroyTime(1.5f) - .intState(POWER, 0, 15) - .enumState(SCULK_SENSOR_PHASE, "inactive", "active", "cooldown") + .intState(POWER) + .enumState(SCULK_SENSOR_PHASE) .booleanState(WATERLOGGED))); public static final Block CALIBRATED_SCULK_SENSOR = register(new Block("calibrated_sculk_sensor", builder().setBlockEntity().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .intState(POWER, 0, 15) - .enumState(SCULK_SENSOR_PHASE, "inactive", "active", "cooldown") + .intState(POWER) + .enumState(SCULK_SENSOR_PHASE) .booleanState(WATERLOGGED))); public static final Block SCULK = register(new Block("sculk", builder().destroyTime(0.2f))); public static final Block SCULK_VEIN = register(new Block("sculk_vein", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) @@ -2466,35 +2466,35 @@ public final class Blocks { public static final Block WAXED_CHISELED_COPPER = register(new Block("waxed_chiseled_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block OXIDIZED_CUT_COPPER_STAIRS = register(new Block("oxidized_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block WEATHERED_CUT_COPPER_STAIRS = register(new Block("weathered_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block EXPOSED_CUT_COPPER_STAIRS = register(new Block("exposed_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block CUT_COPPER_STAIRS = register(new Block("cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block OXIDIZED_CUT_COPPER_SLAB = register(new Block("oxidized_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block WEATHERED_CUT_COPPER_SLAB = register(new Block("weathered_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block EXPOSED_CUT_COPPER_SLAB = register(new Block("exposed_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block CUT_COPPER_SLAB = register(new Block("cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block WAXED_COPPER_BLOCK = register(new Block("waxed_copper_block", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block WAXED_WEATHERED_COPPER = register(new Block("waxed_weathered_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); @@ -2506,129 +2506,129 @@ public final class Blocks { public static final Block WAXED_CUT_COPPER = register(new Block("waxed_cut_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block WAXED_OXIDIZED_CUT_COPPER_STAIRS = register(new Block("waxed_oxidized_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block WAXED_WEATHERED_CUT_COPPER_STAIRS = register(new Block("waxed_weathered_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block WAXED_EXPOSED_CUT_COPPER_STAIRS = register(new Block("waxed_exposed_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block WAXED_CUT_COPPER_STAIRS = register(new Block("waxed_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block WAXED_OXIDIZED_CUT_COPPER_SLAB = register(new Block("waxed_oxidized_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block WAXED_WEATHERED_CUT_COPPER_SLAB = register(new Block("waxed_weathered_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block WAXED_EXPOSED_CUT_COPPER_SLAB = register(new Block("waxed_exposed_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block WAXED_CUT_COPPER_SLAB = register(new Block("waxed_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block COPPER_DOOR = register(new DoorBlock("copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block EXPOSED_COPPER_DOOR = register(new DoorBlock("exposed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block OXIDIZED_COPPER_DOOR = register(new DoorBlock("oxidized_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block WEATHERED_COPPER_DOOR = register(new DoorBlock("weathered_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block WAXED_COPPER_DOOR = register(new DoorBlock("waxed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block WAXED_EXPOSED_COPPER_DOOR = register(new DoorBlock("waxed_exposed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block WAXED_OXIDIZED_COPPER_DOOR = register(new DoorBlock("waxed_oxidized_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block WAXED_WEATHERED_COPPER_DOOR = register(new DoorBlock("waxed_weathered_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block COPPER_TRAPDOOR = register(new TrapDoorBlock("copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block EXPOSED_COPPER_TRAPDOOR = register(new TrapDoorBlock("exposed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block OXIDIZED_COPPER_TRAPDOOR = register(new TrapDoorBlock("oxidized_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block WEATHERED_COPPER_TRAPDOOR = register(new TrapDoorBlock("weathered_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block WAXED_COPPER_TRAPDOOR = register(new TrapDoorBlock("waxed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block WAXED_EXPOSED_COPPER_TRAPDOOR = register(new TrapDoorBlock("waxed_exposed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block WAXED_OXIDIZED_COPPER_TRAPDOOR = register(new TrapDoorBlock("waxed_oxidized_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block WAXED_WEATHERED_COPPER_TRAPDOOR = register(new TrapDoorBlock("waxed_weathered_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); @@ -2677,12 +2677,12 @@ public final class Blocks { .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block POINTED_DRIPSTONE = register(new Block("pointed_dripstone", builder().destroyTime(1.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(DRIPSTONE_THICKNESS, "tip_merge", "tip", "frustum", "middle", "base") + .enumState(DRIPSTONE_THICKNESS) .enumState(VERTICAL_DIRECTION, Direction.UP, Direction.DOWN) .booleanState(WATERLOGGED))); public static final Block DRIPSTONE_BLOCK = register(new Block("dripstone_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block CAVE_VINES = register(new Block("cave_vines", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_25, 0, 25) + .intState(AGE_25) .booleanState(BERRIES))); public static final Block CAVE_VINES_PLANT = register(new Block("cave_vines_plant", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.GLOW_BERRIES) .booleanState(BERRIES))); @@ -2692,18 +2692,18 @@ public final class Blocks { public static final Block MOSS_CARPET = register(new Block("moss_carpet", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY))); public static final Block PINK_PETALS = register(new Block("pink_petals", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .intState(FLOWER_AMOUNT, 1, 4))); + .intState(FLOWER_AMOUNT))); public static final Block MOSS_BLOCK = register(new Block("moss_block", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY))); public static final Block BIG_DRIPLEAF = register(new Block("big_dripleaf", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(TILT, "none", "unstable", "partial", "full") + .enumState(TILT) .booleanState(WATERLOGGED))); public static final Block BIG_DRIPLEAF_STEM = register(new Block("big_dripleaf_stem", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); public static final Block SMALL_DRIPLEAF = register(new Block("small_dripleaf", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOUBLE_BLOCK_HALF) .booleanState(WATERLOGGED))); public static final Block HANGING_ROOTS = register(new Block("hanging_roots", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(WATERLOGGED))); @@ -2714,67 +2714,67 @@ public final class Blocks { public static final Block COBBLED_DEEPSLATE = register(new Block("cobbled_deepslate", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); public static final Block COBBLED_DEEPSLATE_STAIRS = register(new Block("cobbled_deepslate_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block COBBLED_DEEPSLATE_SLAB = register(new Block("cobbled_deepslate_slab", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block COBBLED_DEEPSLATE_WALL = register(new Block("cobbled_deepslate_wall", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block POLISHED_DEEPSLATE = register(new Block("polished_deepslate", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); public static final Block POLISHED_DEEPSLATE_STAIRS = register(new Block("polished_deepslate_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_DEEPSLATE_SLAB = register(new Block("polished_deepslate_slab", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_DEEPSLATE_WALL = register(new Block("polished_deepslate_wall", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block DEEPSLATE_TILES = register(new Block("deepslate_tiles", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); public static final Block DEEPSLATE_TILE_STAIRS = register(new Block("deepslate_tile_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block DEEPSLATE_TILE_SLAB = register(new Block("deepslate_tile_slab", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block DEEPSLATE_TILE_WALL = register(new Block("deepslate_tile_wall", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block DEEPSLATE_BRICKS = register(new Block("deepslate_bricks", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); public static final Block DEEPSLATE_BRICK_STAIRS = register(new Block("deepslate_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block DEEPSLATE_BRICK_SLAB = register(new Block("deepslate_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block DEEPSLATE_BRICK_WALL = register(new Block("deepslate_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block CHISELED_DEEPSLATE = register(new Block("chiseled_deepslate", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); public static final Block CRACKED_DEEPSLATE_BRICKS = register(new Block("cracked_deepslate_bricks", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); public static final Block CRACKED_DEEPSLATE_TILES = register(new Block("cracked_deepslate_tiles", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); @@ -2804,11 +2804,11 @@ public final class Blocks { .booleanState(TRIGGERED))); public static final Block TRIAL_SPAWNER = register(new Block("trial_spawner", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(50.0f) .booleanState(OMINOUS) - .enumState(TRIAL_SPAWNER_STATE, "inactive", "waiting_for_players", "active", "waiting_for_reward_ejection", "ejecting_reward", "cooldown"))); + .enumState(TRIAL_SPAWNER_STATE))); public static final Block VAULT = register(new Block("vault", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(50.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OMINOUS) - .enumState(VAULT_STATE, "inactive", "active", "unlocking", "ejecting"))); + .enumState(VAULT_STATE))); public static final Block HEAVY_CORE = register(new Block("heavy_core", builder().destroyTime(10.0f) .booleanState(WATERLOGGED))); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/BasicEnumProperty.java b/core/src/main/java/org/geysermc/geyser/level/block/property/BasicEnumProperty.java new file mode 100644 index 000000000..f55b85d7b --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/BasicEnumProperty.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.property; + +import java.util.List; + +/** + * Represents enums we don't need classes for in Geyser. + */ +public final class BasicEnumProperty extends Property { + private final List values; + + private BasicEnumProperty(String name, List values) { + super(name); + this.values = values; + } + + @Override + public int valuesCount() { + return this.values.size(); + } + + @Override + public int indexOf(String value) { + int index = this.values.indexOf(value); + if (index == -1) { + throw new IllegalStateException("Property " + this + " does not have value " + value); + } + return index; + } + + @SuppressWarnings("unchecked") + public T values() { + return (T) this.values; + } + + public static BasicEnumProperty create(String name, String... values) { + return new BasicEnumProperty(name, List.of(values)); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/BooleanProperty.java b/core/src/main/java/org/geysermc/geyser/level/block/property/BooleanProperty.java new file mode 100644 index 000000000..56877f537 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/BooleanProperty.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.property; + +public final class BooleanProperty extends Property { + private BooleanProperty(String name) { + super(name); + } + + @Override + public int valuesCount() { + return 2; + } + + @Override + public int indexOf(Boolean value) { + return value ? 0 : 1; + } + + public static BooleanProperty create(String name) { + return new BooleanProperty(name); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/EnumProperty.java b/core/src/main/java/org/geysermc/geyser/level/block/property/EnumProperty.java new file mode 100644 index 000000000..e31f665f9 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/EnumProperty.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.property; + +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; + +public final class EnumProperty> extends Property { + private final IntList ordinalValues; + + /** + * @param values all possible values of this enum. + */ + private EnumProperty(String name, T[] values) { + super(name); + this.ordinalValues = new IntArrayList(values.length); + for (T anEnum : values) { + this.ordinalValues.add(anEnum.ordinal()); + } + } + + @Override + public int valuesCount() { + return this.ordinalValues.size(); + } + + @Override + public int indexOf(T value) { + return this.ordinalValues.indexOf(value.ordinal()); + } + + @SafeVarargs + public static > EnumProperty create(String name, T... values) { + return new EnumProperty<>(name, values); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/IntegerProperty.java b/core/src/main/java/org/geysermc/geyser/level/block/property/IntegerProperty.java new file mode 100644 index 000000000..a772f414d --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/IntegerProperty.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.property; + +public final class IntegerProperty extends Property { + private final int offset; + private final int valuesCount; + + private IntegerProperty(String name, int low, int high) { + super(name); + this.offset = low; + this.valuesCount = high - low; + } + + @Override + public int valuesCount() { + return this.valuesCount; + } + + @Override + public int indexOf(Integer value) { + return value - this.offset; + } + + public int low() { + return this.offset; + } + + public int high() { + return this.offset + this.valuesCount; + } + + public static IntegerProperty create(String name, int low, int high) { + return new IntegerProperty(name, low, high); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java b/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java index 7df09003d..7efa2ef80 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java @@ -29,118 +29,118 @@ import org.geysermc.geyser.level.physics.Axis; import org.geysermc.geyser.level.physics.Direction; public final class Properties { - public static final Property ATTACHED = Property.create("attached"); - public static final Property BOTTOM = Property.create("bottom"); - public static final Property CONDITIONAL = Property.create("conditional"); - public static final Property DISARMED = Property.create("disarmed"); - public static final Property DRAG = Property.create("drag"); - public static final Property ENABLED = Property.create("enabled"); - public static final Property EXTENDED = Property.create("extended"); - public static final Property EYE = Property.create("eye"); - public static final Property FALLING = Property.create("falling"); - public static final Property HANGING = Property.create("hanging"); - public static final Property HAS_BOTTLE_0 = Property.create("has_bottle_0"); - public static final Property HAS_BOTTLE_1 = Property.create("has_bottle_1"); - public static final Property HAS_BOTTLE_2 = Property.create("has_bottle_2"); - public static final Property HAS_RECORD = Property.create("has_record"); - public static final Property HAS_BOOK = Property.create("has_book"); - public static final Property INVERTED = Property.create("inverted"); - public static final Property IN_WALL = Property.create("in_wall"); - public static final Property LIT = Property.create("lit"); - public static final Property LOCKED = Property.create("locked"); - public static final Property OCCUPIED = Property.create("occupied"); - public static final Property OPEN = Property.create("open"); - public static final Property PERSISTENT = Property.create("persistent"); - public static final Property POWERED = Property.create("powered"); - public static final Property SHORT = Property.create("short"); - public static final Property SIGNAL_FIRE = Property.create("signal_fire"); - public static final Property SNOWY = Property.create("snowy"); - public static final Property TRIGGERED = Property.create("triggered"); - public static final Property UNSTABLE = Property.create("unstable"); - public static final Property WATERLOGGED = Property.create("waterlogged"); - public static final Property BERRIES = Property.create("berries"); - public static final Property BLOOM = Property.create("bloom"); - public static final Property SHRIEKING = Property.create("shrieking"); - public static final Property CAN_SUMMON = Property.create("can_summon"); - public static final Property HORIZONTAL_AXIS = Property.create("axis"); - public static final Property AXIS = Property.create("axis"); - public static final Property UP = Property.create("up"); - public static final Property DOWN = Property.create("down"); - public static final Property NORTH = Property.create("north"); - public static final Property EAST = Property.create("east"); - public static final Property SOUTH = Property.create("south"); - public static final Property WEST = Property.create("west"); - public static final Property FACING = Property.create("facing"); - public static final Property FACING_HOPPER = Property.create("facing"); - public static final Property HORIZONTAL_FACING = Property.create("facing"); - public static final Property FLOWER_AMOUNT = Property.create("flower_amount"); - public static final Property ORIENTATION = Property.create("orientation"); - public static final Property ATTACH_FACE = Property.create("face"); - public static final Property BELL_ATTACHMENT = Property.create("attachment"); - public static final Property EAST_WALL = Property.create("east"); - public static final Property NORTH_WALL = Property.create("north"); - public static final Property SOUTH_WALL = Property.create("south"); - public static final Property WEST_WALL = Property.create("west"); - public static final Property EAST_REDSTONE = Property.create("east"); - public static final Property NORTH_REDSTONE = Property.create("north"); - public static final Property SOUTH_REDSTONE = Property.create("south"); - public static final Property WEST_REDSTONE = Property.create("west"); - public static final Property DOUBLE_BLOCK_HALF = Property.create("half"); - public static final Property HALF = Property.create("half"); - public static final Property RAIL_SHAPE = Property.create("shape"); - public static final Property RAIL_SHAPE_STRAIGHT = Property.create("shape"); - public static final Property AGE_1 = Property.create("age"); - public static final Property AGE_2 = Property.create("age"); - public static final Property AGE_3 = Property.create("age"); - public static final Property AGE_4 = Property.create("age"); - public static final Property AGE_5 = Property.create("age"); - public static final Property AGE_7 = Property.create("age"); - public static final Property AGE_15 = Property.create("age"); - public static final Property AGE_25 = Property.create("age"); - public static final Property BITES = Property.create("bites"); - public static final Property CANDLES = Property.create("candles"); - public static final Property DELAY = Property.create("delay"); - public static final Property DISTANCE = Property.create("distance"); - public static final Property EGGS = Property.create("eggs"); - public static final Property HATCH = Property.create("hatch"); - public static final Property LAYERS = Property.create("layers"); - public static final Property LEVEL_CAULDRON = Property.create("level"); - public static final Property LEVEL_COMPOSTER = Property.create("level"); - public static final Property LEVEL_FLOWING = Property.create("level"); - public static final Property LEVEL_HONEY = Property.create("honey_level"); - public static final Property LEVEL = Property.create("level"); - public static final Property MOISTURE = Property.create("moisture"); - public static final Property NOTE = Property.create("note"); - public static final Property PICKLES = Property.create("pickles"); - public static final Property POWER = Property.create("power"); - public static final Property STAGE = Property.create("stage"); - public static final Property STABILITY_DISTANCE = Property.create("distance"); - public static final Property RESPAWN_ANCHOR_CHARGES = Property.create("charges"); - public static final Property ROTATION_16 = Property.create("rotation"); - public static final Property BED_PART = Property.create("part"); - public static final Property CHEST_TYPE = Property.create("type"); - public static final Property MODE_COMPARATOR = Property.create("mode"); - public static final Property DOOR_HINGE = Property.create("hinge"); - public static final Property NOTEBLOCK_INSTRUMENT = Property.create("instrument"); - public static final Property PISTON_TYPE = Property.create("type"); - public static final Property SLAB_TYPE = Property.create("type"); - public static final Property STAIRS_SHAPE = Property.create("shape"); - public static final Property STRUCTUREBLOCK_MODE = Property.create("mode"); - public static final Property BAMBOO_LEAVES = Property.create("leaves"); - public static final Property TILT = Property.create("tilt"); - public static final Property VERTICAL_DIRECTION = Property.create("vertical_direction"); - public static final Property DRIPSTONE_THICKNESS = Property.create("thickness"); - public static final Property SCULK_SENSOR_PHASE = Property.create("sculk_sensor_phase"); - public static final Property CHISELED_BOOKSHELF_SLOT_0_OCCUPIED = Property.create("slot_0_occupied"); - public static final Property CHISELED_BOOKSHELF_SLOT_1_OCCUPIED = Property.create("slot_1_occupied"); - public static final Property CHISELED_BOOKSHELF_SLOT_2_OCCUPIED = Property.create("slot_2_occupied"); - public static final Property CHISELED_BOOKSHELF_SLOT_3_OCCUPIED = Property.create("slot_3_occupied"); - public static final Property CHISELED_BOOKSHELF_SLOT_4_OCCUPIED = Property.create("slot_4_occupied"); - public static final Property CHISELED_BOOKSHELF_SLOT_5_OCCUPIED = Property.create("slot_5_occupied"); - public static final Property DUSTED = Property.create("dusted"); - public static final Property CRACKED = Property.create("cracked"); - public static final Property CRAFTING = Property.create("crafting"); - public static final Property TRIAL_SPAWNER_STATE = Property.create("trial_spawner_state"); - public static final Property VAULT_STATE = Property.create("vault_state"); - public static final Property OMINOUS = Property.create("ominous"); + public static final BooleanProperty ATTACHED = BooleanProperty.create("attached"); + public static final BooleanProperty BOTTOM = BooleanProperty.create("bottom"); + public static final BooleanProperty CONDITIONAL = BooleanProperty.create("conditional"); + public static final BooleanProperty DISARMED = BooleanProperty.create("disarmed"); + public static final BooleanProperty DRAG = BooleanProperty.create("drag"); + public static final BooleanProperty ENABLED = BooleanProperty.create("enabled"); + public static final BooleanProperty EXTENDED = BooleanProperty.create("extended"); + public static final BooleanProperty EYE = BooleanProperty.create("eye"); + public static final BooleanProperty FALLING = BooleanProperty.create("falling"); + public static final BooleanProperty HANGING = BooleanProperty.create("hanging"); + public static final BooleanProperty HAS_BOTTLE_0 = BooleanProperty.create("has_bottle_0"); + public static final BooleanProperty HAS_BOTTLE_1 = BooleanProperty.create("has_bottle_1"); + public static final BooleanProperty HAS_BOTTLE_2 = BooleanProperty.create("has_bottle_2"); + public static final BooleanProperty HAS_RECORD = BooleanProperty.create("has_record"); + public static final BooleanProperty HAS_BOOK = BooleanProperty.create("has_book"); + public static final BooleanProperty INVERTED = BooleanProperty.create("inverted"); + public static final BooleanProperty IN_WALL = BooleanProperty.create("in_wall"); + public static final BooleanProperty LIT = BooleanProperty.create("lit"); + public static final BooleanProperty LOCKED = BooleanProperty.create("locked"); + public static final BooleanProperty OCCUPIED = BooleanProperty.create("occupied"); + public static final BooleanProperty OPEN = BooleanProperty.create("open"); + public static final BooleanProperty PERSISTENT = BooleanProperty.create("persistent"); + public static final BooleanProperty POWERED = BooleanProperty.create("powered"); + public static final BooleanProperty SHORT = BooleanProperty.create("short"); + public static final BooleanProperty SIGNAL_FIRE = BooleanProperty.create("signal_fire"); + public static final BooleanProperty SNOWY = BooleanProperty.create("snowy"); + public static final BooleanProperty TRIGGERED = BooleanProperty.create("triggered"); + public static final BooleanProperty UNSTABLE = BooleanProperty.create("unstable"); + public static final BooleanProperty WATERLOGGED = BooleanProperty.create("waterlogged"); + public static final BooleanProperty BERRIES = BooleanProperty.create("berries"); + public static final BooleanProperty BLOOM = BooleanProperty.create("bloom"); + public static final BooleanProperty SHRIEKING = BooleanProperty.create("shrieking"); + public static final BooleanProperty CAN_SUMMON = BooleanProperty.create("can_summon"); + public static final EnumProperty HORIZONTAL_AXIS = EnumProperty.create("axis", Axis.X, Axis.Z); + public static final EnumProperty AXIS = EnumProperty.create("axis", Axis.VALUES); + public static final BooleanProperty UP = BooleanProperty.create("up"); + public static final BooleanProperty DOWN = BooleanProperty.create("down"); + public static final BooleanProperty NORTH = BooleanProperty.create("north"); + public static final BooleanProperty EAST = BooleanProperty.create("east"); + public static final BooleanProperty SOUTH = BooleanProperty.create("south"); + public static final BooleanProperty WEST = BooleanProperty.create("west"); + public static final EnumProperty FACING = EnumProperty.create("facing", Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN); + public static final EnumProperty FACING_HOPPER = EnumProperty.create("facing", Direction.DOWN, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST); + public static final EnumProperty HORIZONTAL_FACING = EnumProperty.create("facing", Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST); + public static final IntegerProperty FLOWER_AMOUNT = IntegerProperty.create("flower_amount", 1, 4); + public static final EnumProperty ORIENTATION = EnumProperty.create("orientation", FrontAndTop.VALUES); + public static final BasicEnumProperty ATTACH_FACE = BasicEnumProperty.create("face", "floor", "wall", "ceiling"); + public static final BasicEnumProperty BELL_ATTACHMENT = BasicEnumProperty.create("attachment", "floor", "ceiling", "single_wall", "double_wall"); + public static final BasicEnumProperty EAST_WALL = BasicEnumProperty.create("east", "none", "low", "tall"); + public static final BasicEnumProperty NORTH_WALL = BasicEnumProperty.create("north", "none", "low", "tall"); + public static final BasicEnumProperty SOUTH_WALL = BasicEnumProperty.create("south", "none", "low", "tall"); + public static final BasicEnumProperty WEST_WALL = BasicEnumProperty.create("west", "none", "low", "tall"); + public static final BasicEnumProperty EAST_REDSTONE = BasicEnumProperty.create("east", "up", "side", "none"); + public static final BasicEnumProperty NORTH_REDSTONE = BasicEnumProperty.create("north", "up", "side", "none"); + public static final BasicEnumProperty SOUTH_REDSTONE = BasicEnumProperty.create("south", "up", "side", "none"); + public static final BasicEnumProperty WEST_REDSTONE = BasicEnumProperty.create("west", "up", "side", "none"); + public static final BasicEnumProperty DOUBLE_BLOCK_HALF = BasicEnumProperty.create("half", "upper", "lower"); + public static final BasicEnumProperty HALF = BasicEnumProperty.create("half", "top", "bottom"); + public static final BasicEnumProperty RAIL_SHAPE = BasicEnumProperty.create("shape", "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south", "south_east", "south_west", "north_west", "north_east"); + public static final BasicEnumProperty RAIL_SHAPE_STRAIGHT = BasicEnumProperty.create("shape", "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south"); + public static final IntegerProperty AGE_1 = IntegerProperty.create("age", 0, 1); + public static final IntegerProperty AGE_2 = IntegerProperty.create("age", 0, 2); + public static final IntegerProperty AGE_3 = IntegerProperty.create("age", 0, 3); + public static final IntegerProperty AGE_4 = IntegerProperty.create("age", 0, 4); + public static final IntegerProperty AGE_5 = IntegerProperty.create("age", 0, 5); + public static final IntegerProperty AGE_7 = IntegerProperty.create("age", 0, 7); + public static final IntegerProperty AGE_15 = IntegerProperty.create("age", 0, 15); + public static final IntegerProperty AGE_25 = IntegerProperty.create("age", 0, 25); + public static final IntegerProperty BITES = IntegerProperty.create("bites", 0, 6); + public static final IntegerProperty CANDLES = IntegerProperty.create("candles", 1, 4); + public static final IntegerProperty DELAY = IntegerProperty.create("delay", 1, 4); + public static final IntegerProperty DISTANCE = IntegerProperty.create("distance", 1, 7); + public static final IntegerProperty EGGS = IntegerProperty.create("eggs", 1, 4); + public static final IntegerProperty HATCH = IntegerProperty.create("hatch", 0, 2); + public static final IntegerProperty LAYERS = IntegerProperty.create("layers", 1, 8); + public static final IntegerProperty LEVEL_CAULDRON = IntegerProperty.create("level", 1, 3); + public static final IntegerProperty LEVEL_COMPOSTER = IntegerProperty.create("level", 0, 8); + public static final IntegerProperty LEVEL_FLOWING = IntegerProperty.create("level", 1, 8); + public static final IntegerProperty LEVEL_HONEY = IntegerProperty.create("honey_level", 0, 5); + public static final IntegerProperty LEVEL = IntegerProperty.create("level", 0, 15); + public static final IntegerProperty MOISTURE = IntegerProperty.create("moisture", 0, 7); + public static final IntegerProperty NOTE = IntegerProperty.create("note", 0, 24); + public static final IntegerProperty PICKLES = IntegerProperty.create("pickles", 1, 4); + public static final IntegerProperty POWER = IntegerProperty.create("power", 0, 15); + public static final IntegerProperty STAGE = IntegerProperty.create("stage", 0, 1); + public static final IntegerProperty STABILITY_DISTANCE = IntegerProperty.create("distance", 0, 7); + public static final IntegerProperty RESPAWN_ANCHOR_CHARGES = IntegerProperty.create("charges", 0, 4); + public static final IntegerProperty ROTATION_16 = IntegerProperty.create("rotation", 0, 15); + public static final BasicEnumProperty BED_PART = BasicEnumProperty.create("part", "head", "foot"); + public static final EnumProperty CHEST_TYPE = EnumProperty.create("type", ChestType.VALUES); + public static final BasicEnumProperty MODE_COMPARATOR = BasicEnumProperty.create("mode", "compare", "subtract"); + public static final BasicEnumProperty DOOR_HINGE = BasicEnumProperty.create("hinge", "left", "right"); + public static final BasicEnumProperty NOTEBLOCK_INSTRUMENT = BasicEnumProperty.create("instrument", "harp", "basedrum", "snare", "hat", "bass", "flute", "bell", "guitar", "chime", "xylophone", "iron_xylophone", "cow_bell", "didgeridoo", "bit", "banjo", "pling", "zombie", "skeleton", "creeper", "dragon", "wither_skeleton", "piglin", "custom_head"); + public static final BasicEnumProperty PISTON_TYPE = BasicEnumProperty.create("type", "normal", "sticky"); + public static final BasicEnumProperty SLAB_TYPE = BasicEnumProperty.create("type", "top", "bottom", "double"); + public static final BasicEnumProperty STAIRS_SHAPE = BasicEnumProperty.create("shape", "straight", "inner_left", "inner_right", "outer_left", "outer_right"); + public static final BasicEnumProperty STRUCTUREBLOCK_MODE = BasicEnumProperty.create("mode", "save", "load", "corner", "data"); + public static final BasicEnumProperty BAMBOO_LEAVES = BasicEnumProperty.create("leaves", "none", "small", "large"); + public static final BasicEnumProperty TILT = BasicEnumProperty.create("tilt", "none", "unstable", "partial", "full"); + public static final EnumProperty VERTICAL_DIRECTION = EnumProperty.create("vertical_direction", Direction.UP, Direction.DOWN); + public static final BasicEnumProperty DRIPSTONE_THICKNESS = BasicEnumProperty.create("thickness", "tip_merge", "tip", "frustum", "middle", "base"); + public static final BasicEnumProperty SCULK_SENSOR_PHASE = BasicEnumProperty.create("sculk_sensor_phase", "inactive", "active", "cooldown"); + public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_0_OCCUPIED = BooleanProperty.create("slot_0_occupied"); + public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_1_OCCUPIED = BooleanProperty.create("slot_1_occupied"); + public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_2_OCCUPIED = BooleanProperty.create("slot_2_occupied"); + public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_3_OCCUPIED = BooleanProperty.create("slot_3_occupied"); + public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_4_OCCUPIED = BooleanProperty.create("slot_4_occupied"); + public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_5_OCCUPIED = BooleanProperty.create("slot_5_occupied"); + public static final IntegerProperty DUSTED = IntegerProperty.create("dusted", 0, 3); + public static final BooleanProperty CRACKED = BooleanProperty.create("cracked"); + public static final BooleanProperty CRAFTING = BooleanProperty.create("crafting"); + public static final BasicEnumProperty TRIAL_SPAWNER_STATE = BasicEnumProperty.create("trial_spawner_state", "inactive", "waiting_for_players", "active", "waiting_for_reward_ejection", "ejecting_reward", "cooldown"); + public static final BasicEnumProperty VAULT_STATE = BasicEnumProperty.create("vault_state", "inactive", "active", "unlocking", "ejecting"); + public static final BooleanProperty OMINOUS = BooleanProperty.create("ominous"); } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java b/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java index ca5f62daa..0c4713124 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.level.block.property; -public class Property> { +public abstract class Property> { private final String name; - public Property(String name) { + protected Property(String name) { this.name = name; } @@ -36,12 +36,12 @@ public class Property> { return name; } + public abstract int valuesCount(); + + public abstract int indexOf(T value); + @Override public String toString() { return getClass().getSimpleName() + "[" + name + "]"; } - - public static > Property create(String name) { - return new Property<>(name); - } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java index b31c9aeb5..9fe70c0f1 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java @@ -27,9 +27,6 @@ package org.geysermc.geyser.level.block.type; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; -import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; -import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; -import it.unimi.dsi.fastutil.objects.Reference2ObjectMaps; import net.kyori.adventure.key.Key; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3i; @@ -37,6 +34,8 @@ import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.BasicEnumProperty; +import org.geysermc.geyser.level.block.property.IntegerProperty; import org.geysermc.geyser.level.block.property.Property; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; @@ -67,6 +66,12 @@ public class Block { protected Item item = null; private int javaId = -1; + /** + * Used for switching a given block state to different states. + */ + private final Property[] propertyKeys; + private final BlockState defaultState; + public Block(@Subst("empty") String javaIdentifier, Builder builder) { this.javaIdentifier = Key.key(javaIdentifier); this.requiresCorrectToolForDrops = builder.requiresCorrectToolForDrops; @@ -74,7 +79,10 @@ public class Block { this.destroyTime = builder.destroyTime; this.pushReaction = builder.pushReaction; this.pickItem = builder.pickItem; - processStates(builder.build(this)); + + BlockState firstState = builder.build(this).get(0); + this.propertyKeys = builder.propertyKeys; // Ensure this is not null before iterating over states + this.defaultState = setDefaultState(firstState); } public void updateBlock(GeyserSession session, BlockState state, Vector3i position) { @@ -167,9 +175,11 @@ public class Block { } /** - * A list of BlockStates is created pertaining to this block. Do we need any of them? If so, override this method. + * Should only be ran on block creation. Can be overridden. + * @param firstState the first state created from this block */ - protected void processStates(List states) { + protected BlockState setDefaultState(BlockState firstState) { + return firstState; } @NonNull @@ -194,6 +204,10 @@ public class Block { return this.pushReaction; } + public BlockState defaultBlockState() { + return this.defaultState; + } + public int javaId() { return javaId; } @@ -213,6 +227,10 @@ public class Block { '}'; } + Property[] propertyKeys() { + return propertyKeys; + } + public static Builder builder() { return new Builder(); } @@ -225,11 +243,14 @@ public class Block { private float destroyTime; private Supplier pickItem; + // We'll use this field after building + private Property[] propertyKeys; + /** * For states that we're just tracking for mirroring Java states. */ - public Builder enumState(Property property, String... values) { - states.put(property, List.of(values)); + public Builder enumState(BasicEnumProperty property) { + states.put(property, property.values()); return this; } @@ -244,7 +265,9 @@ public class Block { return this; } - public Builder intState(Property property, int low, int high) { + public Builder intState(IntegerProperty property) { + int low = property.low(); + int high = property.high(); IntList list = new IntArrayList(); // There is a state for every number between the low and high. for (int i = low; i <= high; i++) { @@ -283,17 +306,18 @@ public class Block { if (states.isEmpty()) { BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size()); BlockRegistries.BLOCK_STATES.get().add(state); + propertyKeys = null; return List.of(state); } else if (states.size() == 1) { // We can optimize because we don't need to worry about combinations Map.Entry, List>> property = this.states.entrySet().stream().findFirst().orElseThrow(); List states = new ArrayList<>(property.getValue().size()); property.getValue().forEach(value -> { - Reference2ObjectMap, Comparable> propertyMap = Reference2ObjectMaps.singleton(property.getKey(), value); - BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), propertyMap); + BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), new Comparable[] {value}); BlockRegistries.BLOCK_STATES.get().add(state); states.add(state); }); + this.propertyKeys = new Property[]{property.getKey()}; return states; } else { // Think of this stream as another list containing, at the start, one empty list. @@ -327,11 +351,11 @@ public class Block { Property[] keys = this.states.keySet().toArray(new Property[0]); result.forEach(properties -> { Comparable[] values = properties.toArray(new Comparable[0]); - Reference2ObjectMap, Comparable> propertyMap = new Reference2ObjectArrayMap<>(keys, values); - BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), propertyMap); + BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), values); BlockRegistries.BLOCK_STATES.get().add(state); states.add(state); }); + this.propertyKeys = keys; return states; } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java index 4fed30e7a..44271bd80 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java @@ -25,8 +25,7 @@ package org.geysermc.geyser.level.block.type; -import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; -import it.unimi.dsi.fastutil.objects.Reference2ObjectMaps; +import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.level.block.property.Property; import org.geysermc.geyser.registry.BlockRegistries; @@ -35,13 +34,18 @@ import java.util.Locale; public final class BlockState { private final Block block; private final int javaId; - private final Reference2ObjectMap, Comparable> states; + /** + * The values of each property of this block state. These should be treated as keys to {@link Block#propertyKeys()} + * Of note - the comparable part probably doesn't do anything because we occasionally use strings in place of enums. + * Will be null if there's only one block state for a block. + */ + private final Comparable[] states; public BlockState(Block block, int javaId) { - this(block, javaId, Reference2ObjectMaps.emptyMap()); + this(block, javaId, null); } - BlockState(Block block, int javaId, Reference2ObjectMap, Comparable> states) { + BlockState(Block block, int javaId, Comparable[] states) { this.block = block; this.javaId = javaId; this.states = states; @@ -49,23 +53,97 @@ public final class BlockState { public > T getValue(Property property) { //noinspection unchecked - return (T) states.get(property); + return (T) get(property); } public boolean getValue(Property property, boolean def) { - var value = states.get(property); + var value = get(property); if (value == null) { return def; } return (Boolean) value; } + @Nullable + private Comparable get(Property property) { + Property[] keys = this.block.propertyKeys(); + if (keys == null) { + return null; + } + // We're copying the behavior Reference2ObjectArrayMap uses + for (int i = keys.length; i-- != 0;) { + if (keys[i] == property) { + return this.states[i]; + } + } + return null; + } + + /** + * @return the {@link BlockState} instance with the given value. + */ + public > BlockState withValue(Property property, T value) { + Property[] keys = this.block.propertyKeys(); + if (keys == null) { + throw new IllegalStateException(this + " does not have any different states!"); + } + + T currentValue = getValue(property); + if (currentValue == null) { + throw new IllegalArgumentException("This BlockState does not have the property " + property); + } + if (currentValue.equals(value)) { + // No action required. This block state is the state we're looking for. + return this; + } + + // Diff is how much we will have to traverse as a sort of offset + + // Block states are calculated in a predictable structure: + // minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=none] + // minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=low] + // minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=tall] + // minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none] + // minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=low] + // minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=tall] + // minecraft:cobblestone_wall[east=none,north=none,south=none,up=false,waterlogged=true,west=none] + + // The last value goes through all its iterations, then the next state goes through all its iterations. + // West goes none -> low -> tall, then waterlogged is toggled as west cycles again. + // Then when waterlogged goes through all its properties, up is toggled, and west goes through again + // If we want to find the "up" property in order, then we need to find how many iterations each property + // after it goes in. West goes for 3, waterlogged goes for 2. Adding those together, we find that we need to + // add five to get to the next toggle of the up property + int diff = 0; + for (int i = keys.length - 1; i >= 0; i--) { + if (keys[i] != property) { + diff += keys[i].valuesCount(); + } else { + break; + } + } + + // How many times do we have to jump by diff? This depends on how far away each value is from each other. + // piston_head[facing=north] might be right next to piston_head[facing=south], which just one diff'd hop. + // But piston_head[facing=west] is further away, requiring more hops. + int thatOffset = property.indexOf(value); + int thisOffset = property.indexOf(currentValue); + if (diff == 0) { + // This can happen if the property is at the tail end of the block and there are no other properties to look through + // If we have minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=none] + // And want minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=low] + // The above for loop will always stop at the first break because the last property has already been found + diff = 1; + } + return BlockState.of(this.javaId + ((thatOffset - thisOffset) * diff)); + } + public Block block() { - return block; + return this.block; } public int javaId() { - return javaId; + return this.javaId; } public boolean is(Block block) { @@ -74,7 +152,7 @@ public final class BlockState { @Override public String toString() { - if (this.states.isEmpty()) { + if (this.states == null) { return this.block.javaIdentifier().toString(); } return this.block.javaIdentifier().toString() + "[" + paramsToString() + "]"; @@ -82,14 +160,15 @@ public final class BlockState { private String paramsToString() { StringBuilder builder = new StringBuilder(); - var it = this.states.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - builder.append(entry.getKey().name()) - .append("=") - .append(entry.getValue().toString().toLowerCase(Locale.ROOT)); // lowercase covers enums - if (it.hasNext()) { - builder.append(","); + Property[] propertyKeys = this.block.propertyKeys(); + if (propertyKeys != null) { + for (int i = 0; i < propertyKeys.length; i++) { + builder.append(propertyKeys[i].name()) + .append("=") + .append(this.states[i].toString().toLowerCase(Locale.ROOT)); // lowercase covers enums + if (i < propertyKeys.length - 1) { + builder.append(","); + } } } return builder.toString(); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/FurnaceBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/FurnaceBlock.java index 2b898e089..25d54ff2d 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/FurnaceBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/FurnaceBlock.java @@ -28,29 +28,14 @@ package org.geysermc.geyser.level.block.type; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.physics.Direction; -import java.util.List; - public class FurnaceBlock extends Block { - private static BlockState LIT; - private static BlockState UNLIT; - public FurnaceBlock(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } @Override - protected void processStates(List states) { - LIT = states.stream() - .filter(state -> state.getValue(Properties.HORIZONTAL_FACING) == Direction.NORTH - && state.getValue(Properties.LIT)) - .findFirst().orElseThrow(); - UNLIT = states.stream() - .filter(state -> state.getValue(Properties.HORIZONTAL_FACING) == Direction.NORTH - && !state.getValue(Properties.LIT)) - .findFirst().orElseThrow(); - } - - public static BlockState state(boolean lit) { - return lit ? LIT : UNLIT; + protected BlockState setDefaultState(BlockState firstState) { + // Both furnace minecart states look north. + return firstState.withValue(Properties.HORIZONTAL_FACING, Direction.NORTH); } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/HoneyBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/HoneyBlock.java index 73c4d02aa..642240915 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/HoneyBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/HoneyBlock.java @@ -25,21 +25,8 @@ package org.geysermc.geyser.level.block.type; -import java.util.List; - public class HoneyBlock extends Block { - private static BlockState STATE; - public HoneyBlock(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } - - @Override - protected void processStates(List states) { - STATE = states.get(0); - } - - public static BlockState state() { - return STATE; - } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/SpawnerBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/SpawnerBlock.java index 2103fe6e5..968499d11 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/SpawnerBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/SpawnerBlock.java @@ -25,21 +25,8 @@ package org.geysermc.geyser.level.block.type; -import java.util.List; - public class SpawnerBlock extends Block { - private static BlockState STATE; - public SpawnerBlock(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } - - @Override - protected void processStates(List states) { - STATE = states.get(0); - } - - public static BlockState state() { - return STATE; - } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/WaterBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/WaterBlock.java index 801a7f9e7..9d2d23116 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/WaterBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/WaterBlock.java @@ -25,17 +25,8 @@ package org.geysermc.geyser.level.block.type; -import java.util.List; - public class WaterBlock extends Block { - private static BlockState LEVEL_0; - public WaterBlock(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } - - @Override - protected void processStates(List states) { - super.processStates(states); - } } diff --git a/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java b/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java index ce89689eb..2be4e7a38 100644 --- a/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java @@ -39,6 +39,9 @@ import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.PistonCache; import org.geysermc.geyser.translator.collision.BlockCollision; @@ -405,7 +408,8 @@ public class CollisionManager { * @return if the player is currently in a water block */ public boolean isPlayerInWater() { - return session.getGeyser().getWorldManager().getBlockAt(session, session.getPlayerEntity().getPosition().toInt()) == BlockStateValues.JAVA_WATER_ID; + BlockState state = session.getGeyser().getWorldManager().blockAt(session, session.getPlayerEntity().getPosition().toInt()); + return state.is(Blocks.WATER) && state.getValue(Properties.LEVEL) == 0; } public boolean isWaterInEyes() { diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index 1d40386d4..6eadbd0e5 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -50,7 +50,6 @@ import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.api.block.custom.CustomBlockState; import org.geysermc.geyser.api.block.custom.nonvanilla.JavaBlockState; import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.Block; @@ -433,25 +432,13 @@ public final class BlockRegistryPopulator { } int javaRuntimeId = -1; - int waterRuntimeId = -1; for (BlockState javaBlockState : BlockRegistries.BLOCK_STATES.get()) { javaRuntimeId++; String javaId = javaBlockState.toString().intern(); - BlockStateValues.storeBlockStateValues(javaId, javaRuntimeId); - BlockRegistries.JAVA_IDENTIFIER_TO_ID.register(javaId, javaRuntimeId); - - if ("minecraft:water[level=0]".equals(javaId)) { - waterRuntimeId = javaRuntimeId; - } } - if (waterRuntimeId == -1) { - throw new AssertionError("Unable to find Java water in palette"); - } - BlockStateValues.JAVA_WATER_ID = waterRuntimeId; - if (!BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().isEmpty()) { IntSet usedNonVanillaRuntimeIDs = new IntOpenHashSet(); diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java index f618fde46..5c4e835e4 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java @@ -90,6 +90,10 @@ public class BlockMappings implements DefinitionRegistry { return this.getBedrockBlock(javaState.javaId()); } + public GeyserBedrockBlock getVanillaBedrockBlock(BlockState javaState) { + return getVanillaBedrockBlock(javaState.javaId()); + } + public GeyserBedrockBlock getVanillaBedrockBlock(int javaState) { if (javaState < 0 || javaState >= this.javaToVanillaBedrockBlocks.length) { return bedrockAir; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java index 2dfa2a85a..4476391c8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java @@ -31,6 +31,7 @@ import org.geysermc.geyser.inventory.holder.BlockInventoryHolder; import org.geysermc.geyser.inventory.holder.InventoryHolder; import org.geysermc.geyser.inventory.updater.InventoryUpdater; import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; /** @@ -40,17 +41,25 @@ public abstract class AbstractBlockInventoryTranslator extends BaseInventoryTran private final InventoryHolder holder; private final InventoryUpdater updater; + /** + * @param javaBlock a Java block that is used as a temporary block + */ + public AbstractBlockInventoryTranslator(int size, Block javaBlock, ContainerType containerType, InventoryUpdater updater, + Block... additionalValidBlocks) { + this(size, javaBlock.defaultBlockState(), containerType, updater, additionalValidBlocks); + } + /** * @param size the amount of slots that the inventory adds alongside the base inventory slots - * @param javaBlockIdentifier a Java block identifier that is used as a temporary block + * @param javaBlockState a Java block state that is used as a temporary block * @param containerType the container type of this inventory * @param updater updater * @param additionalValidBlocks any other blocks that can safely use this inventory without a fake block */ - public AbstractBlockInventoryTranslator(int size, String javaBlockIdentifier, ContainerType containerType, InventoryUpdater updater, + public AbstractBlockInventoryTranslator(int size, BlockState javaBlockState, ContainerType containerType, InventoryUpdater updater, Block... additionalValidBlocks) { super(size); - this.holder = new BlockInventoryHolder(javaBlockIdentifier, containerType, additionalValidBlocks); + this.holder = new BlockInventoryHolder(javaBlockState, containerType, additionalValidBlocks); this.updater = updater; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java index 705fac362..40ee28362 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java @@ -45,7 +45,7 @@ import java.util.Objects; public class AnvilInventoryTranslator extends AbstractBlockInventoryTranslator { public AnvilInventoryTranslator() { - super(3, "minecraft:anvil[facing=north]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.ANVIL, AnvilInventoryUpdater.INSTANCE, + super(3, Blocks.ANVIL, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.ANVIL, AnvilInventoryUpdater.INSTANCE, Blocks.CHIPPED_ANVIL, Blocks.DAMAGED_ANVIL); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java index 9aeeff007..ceae1b640 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java @@ -27,7 +27,6 @@ package org.geysermc.geyser.translator.inventory; import it.unimi.dsi.fastutil.ints.IntSets; import org.cloudburstmc.math.vector.Vector3i; -import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest; @@ -43,7 +42,9 @@ import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.holder.BlockInventoryHolder; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; import org.geysermc.geyser.util.InventoryUtils; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetBeaconPacket; @@ -52,7 +53,7 @@ import java.util.OptionalInt; public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator { public BeaconInventoryTranslator() { - super(1, new BlockInventoryHolder("minecraft:beacon", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.BEACON) { + super(1, new BlockInventoryHolder(Blocks.BEACON, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.BEACON) { @Override protected boolean checkInteractionPosition(GeyserSession session) { // Since we can't fall back to a virtual inventory, let's make opening one easier @@ -89,12 +90,8 @@ public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator // Send a block entity data packet update to the fake beacon inventory Vector3i position = inventory.getHolderPosition(); - NbtMapBuilder builder = NbtMap.builder() - .putInt("x", position.getX()) - .putInt("y", position.getY()) - .putInt("z", position.getZ()) + NbtMapBuilder builder = BlockEntityTranslator.getConstantBedrockTag("Beacon", position) .putString("CustomName", inventory.getTitle()) - .putString("id", "Beacon") .putInt("primary", beaconContainer.getPrimaryId()) .putInt("secondary", beaconContainer.getSecondaryId()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/BrewingInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/BrewingInventoryTranslator.java index a2c45384d..e425342f3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/BrewingInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/BrewingInventoryTranslator.java @@ -32,11 +32,16 @@ import org.cloudburstmc.protocol.bedrock.packet.ContainerSetDataPacket; import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.session.GeyserSession; public class BrewingInventoryTranslator extends AbstractBlockInventoryTranslator { public BrewingInventoryTranslator() { - super(5, "minecraft:brewing_stand[has_bottle_0=false,has_bottle_1=false,has_bottle_2=false]", ContainerType.BREWING_STAND, ContainerInventoryUpdater.INSTANCE); + super(5, Blocks.BREWING_STAND.defaultBlockState() + .withValue(Properties.HAS_BOTTLE_0, false) + .withValue(Properties.HAS_BOTTLE_1, false) + .withValue(Properties.HAS_BOTTLE_2, false), ContainerType.BREWING_STAND, ContainerInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java index a115bd953..b0914e5dd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java @@ -30,12 +30,13 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemSt import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; public class CartographyInventoryTranslator extends AbstractBlockInventoryTranslator { public CartographyInventoryTranslator() { - super(3, "minecraft:cartography_table", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.CARTOGRAPHY, UIInventoryUpdater.INSTANCE); + super(3, Blocks.CARTOGRAPHY_TABLE, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.CARTOGRAPHY, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java index 2a2f5beb5..8b0a0ac44 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java @@ -31,6 +31,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.updater.CrafterInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; @@ -53,7 +54,7 @@ public class CrafterInventoryTranslator extends AbstractBlockInventoryTranslator private static final int TRIGGERED = 1; // triggered value public CrafterInventoryTranslator() { - super(10, "minecraft:crafter", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.CRAFTER, CrafterInventoryUpdater.INSTANCE); + super(10, Blocks.CRAFTER, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.CRAFTER, CrafterInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/CraftingInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/CraftingInventoryTranslator.java index 521db494a..4a0f1d7d9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/CraftingInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/CraftingInventoryTranslator.java @@ -31,10 +31,11 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemSt import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.SlotType; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; public class CraftingInventoryTranslator extends AbstractBlockInventoryTranslator { public CraftingInventoryTranslator() { - super(10, "minecraft:crafting_table", ContainerType.WORKBENCH, UIInventoryUpdater.INSTANCE); + super(10, Blocks.CRAFTING_TABLE, ContainerType.WORKBENCH, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java index 8fee2a391..e1407346a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java @@ -38,6 +38,7 @@ import org.cloudburstmc.protocol.bedrock.packet.PlayerEnchantOptionsPacket; import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; @@ -47,7 +48,7 @@ import java.util.Locale; public class EnchantingInventoryTranslator extends AbstractBlockInventoryTranslator { public EnchantingInventoryTranslator() { - super(2, "minecraft:enchanting_table", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.ENCHANTMENT, UIInventoryUpdater.INSTANCE); + super(2, Blocks.ENCHANTING_TABLE, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.ENCHANTMENT, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java index f47a367d8..80040e375 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java @@ -41,7 +41,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; */ public class Generic3X3InventoryTranslator extends AbstractBlockInventoryTranslator { public Generic3X3InventoryTranslator() { - super(9, "minecraft:dispenser[facing=north,triggered=false]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.DISPENSER, ContainerInventoryUpdater.INSTANCE, + super(9, Blocks.DISPENSER, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.DISPENSER, ContainerInventoryUpdater.INSTANCE, Blocks.DROPPER); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/GrindstoneInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/GrindstoneInventoryTranslator.java index a32b97b70..5344d27cb 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/GrindstoneInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/GrindstoneInventoryTranslator.java @@ -30,10 +30,11 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; public class GrindstoneInventoryTranslator extends AbstractBlockInventoryTranslator { public GrindstoneInventoryTranslator() { - super(3, "minecraft:grindstone[face=floor,facing=north]", ContainerType.GRINDSTONE, UIInventoryUpdater.INSTANCE); + super(3, Blocks.GRINDSTONE, ContainerType.GRINDSTONE, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/HopperInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/HopperInventoryTranslator.java index dab1ee972..fdcd7bf57 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/HopperInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/HopperInventoryTranslator.java @@ -29,13 +29,14 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; /** * Implemented on top of any block that does not have special properties implemented */ public class HopperInventoryTranslator extends AbstractBlockInventoryTranslator { public HopperInventoryTranslator() { - super(5, "minecraft:hopper[enabled=false,facing=down]", ContainerType.HOPPER, ContainerInventoryUpdater.INSTANCE); + super(5, Blocks.HOPPER, ContainerType.HOPPER, ContainerInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java index f3bbc9b87..c6c3c7dd6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java @@ -34,6 +34,7 @@ import org.geysermc.erosion.util.LecternUtils; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; @@ -56,7 +57,7 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator private boolean initialized = false; public LecternInventoryTranslator() { - super(1, "minecraft:lectern[facing=north,has_book=true,powered=true]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.LECTERN , ContainerInventoryUpdater.INSTANCE); + super(1, Blocks.LECTERN, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.LECTERN , ContainerInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java index e8571c8fb..0694e2ac6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java @@ -45,6 +45,7 @@ import org.geysermc.geyser.inventory.SlotType; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.item.type.BannerItem; import org.geysermc.geyser.item.type.DyeItem; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; @@ -101,7 +102,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator { } public LoomInventoryTranslator() { - super(4, "minecraft:loom[facing=north]", ContainerType.LOOM, UIInventoryUpdater.INSTANCE); + super(4, Blocks.LOOM, ContainerType.LOOM, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java index 201c900d6..21fe9ca21 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java @@ -37,6 +37,7 @@ import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket; import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InventoryUtils; @@ -53,7 +54,7 @@ public class OldSmithingTableTranslator extends AbstractBlockInventoryTranslator private static final IntFunction UPGRADE_TEMPLATE = InventoryUtils.getUpgradeTemplate(); private OldSmithingTableTranslator() { - super(3, "minecraft:smithing_table", ContainerType.SMITHING_TABLE, UIInventoryUpdater.INSTANCE); + super(3, Blocks.SMITHING_TABLE, ContainerType.SMITHING_TABLE, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java index 72f5260a0..464bf07f7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java @@ -35,7 +35,10 @@ import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.holder.BlockInventoryHolder; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; @@ -43,12 +46,13 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType public class ShulkerInventoryTranslator extends AbstractBlockInventoryTranslator { public ShulkerInventoryTranslator() { - super(27, new BlockInventoryHolder("minecraft:shulker_box[facing=north]", ContainerType.CONTAINER) { + // Ensure that the shulker box default state won't be trying to open in a state facing the player + super(27, new BlockInventoryHolder(Blocks.SHULKER_BOX.defaultBlockState().withValue(Properties.FACING, Direction.NORTH), ContainerType.CONTAINER) { private final BlockEntityTranslator shulkerBoxTranslator = Registries.BLOCK_ENTITIES.get(BlockEntityType.SHULKER_BOX); @Override - protected boolean isValidBlock(String[] javaBlockString) { - return javaBlockString[0].contains("shulker_box"); + protected boolean isValidBlock(BlockState blockState) { + return blockState.block().javaIdentifier().value().contains("shulker_box"); // TODO ew } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/SmithingInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/SmithingInventoryTranslator.java index 730e4a451..c68347fd3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/SmithingInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/SmithingInventoryTranslator.java @@ -30,10 +30,11 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; public class SmithingInventoryTranslator extends AbstractBlockInventoryTranslator { public SmithingInventoryTranslator() { - super(4, "minecraft:smithing_table", ContainerType.SMITHING_TABLE, UIInventoryUpdater.INSTANCE); + super(4, Blocks.SMITHING_TABLE, ContainerType.SMITHING_TABLE, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java index 54f2f447b..b977ee1a1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java @@ -35,6 +35,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemS import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; @@ -42,7 +43,7 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.S public class StonecutterInventoryTranslator extends AbstractBlockInventoryTranslator { public StonecutterInventoryTranslator() { - super(2, "minecraft:stonecutter[facing=north]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.STONECUTTER, UIInventoryUpdater.INSTANCE); + super(2, Blocks.STONECUTTER, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.STONECUTTER, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java index 4c49c8e5a..4bc727397 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java @@ -40,6 +40,7 @@ import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.property.ChestType; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; @@ -51,7 +52,10 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { public DoubleChestInventoryTranslator(int size) { super(size, 54); - this.defaultJavaBlockState = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt("minecraft:chest[facing=north,type=single,waterlogged=false]"); + this.defaultJavaBlockState = Blocks.CHEST.defaultBlockState() + .withValue(Properties.HORIZONTAL_FACING, Direction.NORTH) + .withValue(Properties.CHEST_TYPE, ChestType.SINGLE) + .javaId(); } @Override @@ -96,11 +100,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { blockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY); session.sendUpstreamPacket(blockPacket); - NbtMap tag = NbtMap.builder() - .putString("id", "Chest") - .putInt("x", position.getX()) - .putInt("y", position.getY()) - .putInt("z", position.getZ()) + NbtMap tag = BlockEntityTranslator.getConstantBedrockTag("Chest", position) .putInt("pairx", pairPosition.getX()) .putInt("pairz", pairPosition.getZ()) .putString("CustomName", inventory.getTitle()).build(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java index e18096862..264b2eb29 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java @@ -30,6 +30,9 @@ import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.holder.BlockInventoryHolder; import org.geysermc.geyser.inventory.holder.InventoryHolder; import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.ChestType; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; public class SingleChestInventoryTranslator extends ChestInventoryTranslator { @@ -38,17 +41,17 @@ public class SingleChestInventoryTranslator extends ChestInventoryTranslator { // TODO add barrel??? public SingleChestInventoryTranslator(int size) { super(size, 27); - this.holder = new BlockInventoryHolder("minecraft:chest[facing=north,type=single,waterlogged=false]", ContainerType.CONTAINER, + this.holder = new BlockInventoryHolder(Blocks.CHEST.defaultBlockState().withValue(Properties.CHEST_TYPE, ChestType.SINGLE), ContainerType.CONTAINER, Blocks.ENDER_CHEST, Blocks.TRAPPED_CHEST) { @Override - protected boolean isValidBlock(String[] javaBlockString) { - if (javaBlockString[0].equals("minecraft:ender_chest")) { + protected boolean isValidBlock(BlockState blockState) { + if (blockState.is(Blocks.ENDER_CHEST)) { // Can't have double ender chests return true; } // Add provision to ensure this isn't a double chest - return super.isValidBlock(javaBlockString) && (javaBlockString.length > 1 && javaBlockString[1].contains("type=single")); + return super.isValidBlock(blockState) && blockState.getValue(Properties.CHEST_TYPE) == ChestType.SINGLE; } }; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/AbstractFurnaceInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/AbstractFurnaceInventoryTranslator.java index 6cda03a19..8991ef787 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/AbstractFurnaceInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/AbstractFurnaceInventoryTranslator.java @@ -32,12 +32,14 @@ import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.SlotType; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.AbstractBlockInventoryTranslator; public abstract class AbstractFurnaceInventoryTranslator extends AbstractBlockInventoryTranslator { - AbstractFurnaceInventoryTranslator(String javaBlockIdentifier, ContainerType containerType) { - super(3, javaBlockIdentifier, containerType, ContainerInventoryUpdater.INSTANCE); + AbstractFurnaceInventoryTranslator(Block javaBlock, ContainerType containerType) { + super(3, javaBlock.defaultBlockState().withValue(Properties.LIT, false), containerType, ContainerInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/BlastFurnaceInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/BlastFurnaceInventoryTranslator.java index 0b6e0c674..185cafc51 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/BlastFurnaceInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/BlastFurnaceInventoryTranslator.java @@ -28,10 +28,11 @@ package org.geysermc.geyser.translator.inventory.furnace; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.geysermc.geyser.inventory.BedrockContainerSlot; +import org.geysermc.geyser.level.block.Blocks; public class BlastFurnaceInventoryTranslator extends AbstractFurnaceInventoryTranslator { public BlastFurnaceInventoryTranslator() { - super("minecraft:blast_furnace[facing=north,lit=false]", ContainerType.BLAST_FURNACE); + super(Blocks.BLAST_FURNACE, ContainerType.BLAST_FURNACE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/FurnaceInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/FurnaceInventoryTranslator.java index 95a79a93e..bc96f7105 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/FurnaceInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/FurnaceInventoryTranslator.java @@ -28,10 +28,11 @@ package org.geysermc.geyser.translator.inventory.furnace; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.geysermc.geyser.inventory.BedrockContainerSlot; +import org.geysermc.geyser.level.block.Blocks; public class FurnaceInventoryTranslator extends AbstractFurnaceInventoryTranslator { public FurnaceInventoryTranslator() { - super("minecraft:furnace[facing=north,lit=false]", ContainerType.FURNACE); + super(Blocks.FURNACE, ContainerType.FURNACE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/SmokerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/SmokerInventoryTranslator.java index 2f87f3b13..380446f09 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/SmokerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/SmokerInventoryTranslator.java @@ -28,10 +28,11 @@ package org.geysermc.geyser.translator.inventory.furnace; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.geysermc.geyser.inventory.BedrockContainerSlot; +import org.geysermc.geyser.level.block.Blocks; public class SmokerInventoryTranslator extends AbstractFurnaceInventoryTranslator { public SmokerInventoryTranslator() { - super("minecraft:smoker[facing=north,lit=false]", ContainerType.SMOKER); + super(Blocks.SMOKER, ContainerType.SMOKER); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java index ca8679319..350ce8c3e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java @@ -26,22 +26,24 @@ package org.geysermc.geyser.translator.level.block.entity; import it.unimi.dsi.fastutil.ints.IntArrays; -import it.unimi.dsi.fastutil.objects.*; -import org.geysermc.geyser.level.block.Blocks; -import org.geysermc.geyser.level.block.type.Block; -import org.geysermc.geyser.level.block.type.BlockState; -import org.geysermc.geyser.level.block.type.HoneyBlock; -import org.geysermc.geyser.level.block.type.PistonBlock; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectMaps; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import lombok.Getter; import org.cloudburstmc.math.vector.Vector3d; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; -import lombok.Getter; import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.block.type.PistonBlock; import org.geysermc.geyser.level.physics.Axis; import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.level.physics.CollisionManager; @@ -53,6 +55,7 @@ import org.geysermc.geyser.translator.collision.BlockCollision; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.geyser.util.BlockUtils; import org.geysermc.geyser.util.ChunkUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; import java.util.LinkedList; import java.util.Map; @@ -99,7 +102,7 @@ public class PistonBlockEntity { static { // Create a ~1 x ~0.5 x ~1 bounding box above the honey block - BlockCollision blockCollision = BlockRegistries.COLLISIONS.get(HoneyBlock.state().javaId()); + BlockCollision blockCollision = BlockRegistries.COLLISIONS.get(Blocks.HONEY_BLOCK.defaultBlockState().javaId()); if (blockCollision == null) { throw new RuntimeException("Failed to find honey block collision"); } @@ -224,10 +227,10 @@ public class PistonBlockEntity { private void removePistonHead() { Vector3i blockInFront = position.add(orientation.getUnitVector()); - int blockId = session.getGeyser().getWorldManager().getBlockAt(session, blockInFront); - if (BlockStateValues.isPistonHead(blockId)) { + BlockState state = session.getGeyser().getWorldManager().blockAt(session, blockInFront); + if (state.is(Blocks.PISTON_HEAD)) { ChunkUtils.updateBlock(session, Block.JAVA_AIR_ID, blockInFront); - } else if ((session.getGeyser().getPlatformType() == PlatformType.SPIGOT || session.getErosionHandler().isActive()) && blockId == Block.JAVA_AIR_ID) { + } else if ((session.getGeyser().getPlatformType() == PlatformType.SPIGOT || session.getErosionHandler().isActive()) && state.is(Blocks.AIR)) { // Spigot removes the piston head from the cache, but we need to send the block update ourselves ChunkUtils.updateBlock(session, Block.JAVA_AIR_ID, blockInFront); } @@ -353,7 +356,9 @@ public class PistonBlockEntity { playerBoundingBox.setSizeZ(playerBoundingBox.getSizeZ() - shrink.getZ()); // Resolve collision with the piston head - BlockState pistonHeadId = BlockState.of(BlockStateValues.getPistonHead(orientation)); + BlockState pistonHeadId = Blocks.PISTON_HEAD.defaultBlockState() + .withValue(Properties.SHORT, false) + .withValue(Properties.FACING, orientation); pushPlayerBlock(pistonHeadId, getPistonHeadPos().toDouble(), blockMovement, playerBoundingBox); // Resolve collision with any attached moving blocks, but skip slime blocks @@ -562,9 +567,11 @@ public class PistonBlockEntity { private BlockState getAttachedBlockId(Vector3i blockPos) { if (blockPos.equals(getPistonHeadPos())) { - return BlockState.of(BlockStateValues.getPistonHead(orientation)); + return Blocks.PISTON_HEAD.defaultBlockState() + .withValue(Properties.SHORT, false) + .withValue(Properties.FACING, orientation); } else { - return attachedBlocks.getOrDefault(blockPos, BlockState.of(Block.JAVA_AIR_ID)); //FIXME + return attachedBlocks.getOrDefault(blockPos, Blocks.AIR.defaultBlockState()); } } @@ -633,7 +640,9 @@ public class PistonBlockEntity { if (action == PistonValueType.PUSHING) { Vector3i pistonHeadPos = getPistonHeadPos().add(movement); if (!SOLID_BOUNDING_BOX.checkIntersection(pistonHeadPos.toDouble(), session.getCollisionManager().getPlayerBoundingBox())) { - ChunkUtils.updateBlock(session, BlockStateValues.getPistonHead(orientation), pistonHeadPos); + ChunkUtils.updateBlock(session, Blocks.PISTON_HEAD.defaultBlockState() + .withValue(Properties.SHORT, false) + .withValue(Properties.FACING, orientation), pistonHeadPos); } } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java index 25f9f5497..878d326ac 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java @@ -56,8 +56,8 @@ import org.geysermc.geyser.item.type.BlockItem; import org.geysermc.geyser.item.type.BoatItem; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.item.type.SpawnEggItem; -import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.block.type.CauldronBlock; @@ -295,10 +295,10 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator { - private static final String[] ALL_BLOCK_NAMES = BlockRegistries.JAVA_BLOCKS.get().stream().map(block -> block.javaIdentifier().toString()).toArray(String[]::new); + /** + * Wait until the registries load before getting all the block names. + */ + private static final Supplier ALL_BLOCK_NAMES = Suppliers.memoize(() -> BlockRegistries.JAVA_BLOCKS.get().stream().map(block -> block.javaIdentifier().toString()).toArray(String[]::new)); private static final String[] ALL_EFFECT_IDENTIFIERS = EntityUtils.getAllEffectIdentifiers(); private static final String[] ATTRIBUTES = AttributeType.Builtin.BUILTIN.values().stream().map(AttributeType::getIdentifier).toList().toArray(new String[0]); private static final String[] ENUM_BOOLEAN = {"true", "false"}; @@ -247,7 +252,7 @@ public class JavaCommandsTranslator extends PacketTranslator CommandParam.FILE_PATH; case BOOL -> ENUM_BOOLEAN; case OPERATION -> CommandParam.OPERATOR; // ">=", "==", etc - case BLOCK_STATE -> ALL_BLOCK_NAMES; + case BLOCK_STATE -> ALL_BLOCK_NAMES.get(); case ITEM_STACK -> context.getItemNames(); case COLOR -> VALID_COLORS; case SCOREBOARD_SLOT -> VALID_SCOREBOARD_SLOTS; diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3a3a2d20c..aa68a0bc0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -65,7 +65,6 @@ fastutil-int-byte-maps = { group = "com.nukkitx.fastutil", name = "fastutil-int- fastutil-int-boolean-maps = { group = "com.nukkitx.fastutil", name = "fastutil-int-boolean-maps", version.ref = "fastutil" } fastutil-object-int-maps = { group = "com.nukkitx.fastutil", name = "fastutil-object-int-maps", version.ref = "fastutil" } fastutil-object-object-maps = { group = "com.nukkitx.fastutil", name = "fastutil-object-object-maps", version.ref = "fastutil" } -fastutil-reference-object-maps = { group = "com.nukkitx.fastutil", name = "fastutil-reference-object-maps", version.ref = "fastutil" } adventure-text-serializer-gson = { group = "net.kyori", name = "adventure-text-serializer-gson", version.ref = "adventure" } # Remove when we remove our Adventure bump adventure-text-serializer-legacy = { group = "net.kyori", name = "adventure-text-serializer-legacy", version.ref = "adventure" } @@ -143,7 +142,7 @@ blossom = { id = "net.kyori.blossom", version.ref = "blossom" } [bundles] jackson = [ "jackson-annotations", "jackson-core", "jackson-dataformat-yaml" ] -fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps", "fastutil-reference-object-maps" ] +fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps" ] adventure = [ "adventure-text-serializer-gson", "adventure-text-serializer-legacy", "adventure-text-serializer-plain" ] log4j = [ "log4j-api", "log4j-core", "log4j-slf4j2-impl" ] jline = [ "jline-terminal", "jline-terminal-jna", "jline-reader" ] From 96bfda2ed3f53a90266876b8b8741d2052dfa8ef Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 21 May 2024 20:37:18 -0400 Subject: [PATCH 7/9] Fix #4683 --- .../geyser/session/cache/LodestoneCache.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java index 50cdf4b5b..f66daf027 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java @@ -28,7 +28,6 @@ package org.geysermc.geyser.session.cache; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.checkerframework.checker.nullness.qual.Nullable; -import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos; import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker; @@ -53,11 +52,13 @@ public final class LodestoneCache { private int id = 1; public void cacheInventoryItem(GeyserItemStack itemStack, LodestoneTracker tracker) { - GlobalPos position = tracker.getPos(); + if (!tracker.isTracked()) { + return; + } + GlobalPos position = tracker.getPos(); if (position == null) { - GeyserImpl.getInstance().getLogger().error("Position is null. Find out why."); - Thread.dumpStack(); + // As of 1.20.6, position can still be null even if tracking is enabled. return; } int x = position.getX(); @@ -84,13 +85,16 @@ public final class LodestoneCache { } public int store(LodestoneTracker tracker) { - GlobalPos position = tracker.getPos(); - - if (position == null) { - GeyserImpl.getInstance().getLogger().error("Position is null. Find out why."); - Thread.dumpStack(); - return -1; + if (!tracker.isTracked()) { + // No coordinates; nothing to convert + return 0; } + + GlobalPos position = tracker.getPos(); + if (position == null) { + return 0; + } + int x = position.getX(); int y = position.getY(); int z = position.getZ(); From f7b026d61b7f07459542928bdd3766843724a43b Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 21 May 2024 20:56:13 -0400 Subject: [PATCH 8/9] Remove old sneaking/crawling workarounds Since Bedrock implements these natively, there's no need for extra checks. :) --- .../type/player/SessionPlayerEntity.java | 34 ----------- .../geyser/session/GeyserSession.java | 58 ++----------------- 2 files changed, 4 insertions(+), 88 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java index e10adb134..ca541b5d3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java @@ -31,7 +31,6 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.AttributeData; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; import org.geysermc.geyser.entity.attribute.GeyserAttributeType; import org.geysermc.geyser.item.Items; @@ -60,10 +59,6 @@ public class SessionPlayerEntity extends PlayerEntity { */ @Getter protected final Map attributes = new Object2ObjectOpenHashMap<>(); - /** - * Whether to check for updated speed after all entity metadata has been processed - */ - private boolean refreshSpeed = false; /** * Used in PlayerInputTranslator for movement checks. */ @@ -120,9 +115,7 @@ public class SessionPlayerEntity extends PlayerEntity { // TODO: proper fix, BDS somehow does it? https://paste.gg/p/anonymous/3adfb7612f1540be80fa03a2281f93dc (BDS 1.20.13) if (!this.session.getGameMode().equals(GameMode.SPECTATOR)) { super.setFlags(entityMetadata); - session.setSwimmingInWater((entityMetadata.getPrimitiveValue() & 0x10) == 0x10 && getFlag(EntityFlag.SPRINTING)); } - refreshSpeed = true; } /** @@ -150,7 +143,6 @@ public class SessionPlayerEntity extends PlayerEntity { public void setPose(Pose pose) { super.setPose(pose); session.setPose(pose); - refreshSpeed = true; } public float getMaxHealth() { @@ -199,21 +191,6 @@ public class SessionPlayerEntity extends PlayerEntity { } } - @Override - public void updateBedrockMetadata() { - super.updateBedrockMetadata(); - if (refreshSpeed) { - AttributeData speedAttribute = session.adjustSpeed(); - if (speedAttribute != null) { - UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); - attributesPacket.setRuntimeEntityId(geyserId); - attributesPacket.setAttributes(Collections.singletonList(speedAttribute)); - session.sendUpstreamPacket(attributesPacket); - } - refreshSpeed = false; - } - } - @Override protected void updateAttribute(Attribute javaAttribute, List newAttributes) { if (javaAttribute.getType() == AttributeType.Builtin.GENERIC_ATTACK_SPEED) { @@ -226,17 +203,6 @@ public class SessionPlayerEntity extends PlayerEntity { @Override protected AttributeData calculateAttribute(Attribute javaAttribute, GeyserAttributeType type) { AttributeData attributeData = super.calculateAttribute(javaAttribute, type); - - if (javaAttribute.getType() == AttributeType.Builtin.GENERIC_MOVEMENT_SPEED) { - session.setOriginalSpeedAttribute(attributeData.getValue()); - AttributeData speedAttribute = session.adjustSpeed(); - if (speedAttribute != null) { - // Overwrite the attribute with our own - this.attributes.put(type, speedAttribute); - return speedAttribute; - } - } - this.attributes.put(type, attributeData); return attributeData; } diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index c85c0fd28..aa256df55 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -317,22 +317,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Setter private boolean sprinting; - /** - * Whether the player is swimming in water. - * Used to update speed when crawling. - */ - @Setter - private boolean swimmingInWater; - - /** - * Tracks the original speed attribute. - *

- * We need to do this in order to emulate speeds when sneaking under 1.5-blocks-tall areas if the player isn't sneaking, - * and when crawling. - */ - @Setter - private float originalSpeedAttribute; - /** * The dimension of the player. * As all entities are in the same world, this can be safely applied to all other entities. @@ -1283,21 +1267,11 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { this.sneaking = sneaking; // Update pose and bounding box on our end - AttributeData speedAttribute; - if (!sneaking && (speedAttribute = adjustSpeed()) != null) { - // Update attributes since we're still "sneaking" under a 1.5-block-tall area - UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); - attributesPacket.setRuntimeEntityId(playerEntity.getGeyserId()); - attributesPacket.setAttributes(Collections.singletonList(speedAttribute)); - sendUpstreamPacket(attributesPacket); - // the server *should* update our pose once it has returned to normal - } else { - if (!flying) { - // The pose and bounding box should not be updated if the player is flying - setSneakingPose(sneaking); - } - collisionManager.updateScaffoldingFlags(false); + if (!flying) { + // The pose and bounding box should not be updated if the player is flying + setSneakingPose(sneaking); } + collisionManager.updateScaffoldingFlags(false); playerEntity.updateBedrockMetadata(); @@ -1340,30 +1314,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { } } - /** - * Adjusts speed if the player is crawling. - * - * @return not null if attributes should be updated. - */ - public @Nullable AttributeData adjustSpeed() { - AttributeData currentPlayerSpeed = playerEntity.getAttributes().get(GeyserAttributeType.MOVEMENT_SPEED); - if (currentPlayerSpeed != null) { - if ((pose.equals(Pose.SNEAKING) && !sneaking && collisionManager.mustPlayerSneakHere()) || - (!swimmingInWater && playerEntity.getFlag(EntityFlag.SWIMMING) && !collisionManager.isPlayerInWater())) { - // Either of those conditions means that Bedrock goes zoom when they shouldn't be - AttributeData speedAttribute = GeyserAttributeType.MOVEMENT_SPEED.getAttribute(originalSpeedAttribute / 3.32f); - playerEntity.getAttributes().put(GeyserAttributeType.MOVEMENT_SPEED, speedAttribute); - return speedAttribute; - } else if (originalSpeedAttribute != currentPlayerSpeed.getValue()) { - // Speed has reset to normal - AttributeData speedAttribute = GeyserAttributeType.MOVEMENT_SPEED.getAttribute(originalSpeedAttribute); - playerEntity.getAttributes().put(GeyserAttributeType.MOVEMENT_SPEED, speedAttribute); - return speedAttribute; - } - } - return null; - } - /** * Checks to see if a shield is in either hand to activate blocking. If so, it sets the Bedrock client to display * blocking and sends a packet to the Java server. From 6f4c29c834b4f111ee9807da89fc3aa83d93c83d Mon Sep 17 00:00:00 2001 From: gecko10000 <60494179+gecko10000@users.noreply.github.com> Date: Wed, 22 May 2024 02:26:32 -0700 Subject: [PATCH 9/9] Match Advancement Packet Behavior Towards Java (#4684) * Send advancement packet regardless of current tab * Send advancement close packet when single-advancement form closed --- .../geyser/session/cache/AdvancementsCache.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java index 6769b4330..be1eb3a5b 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java @@ -91,11 +91,9 @@ public class AdvancementsCache { builder.validResultHandler((response) -> { String id = rootAdvancementIds.get(response.clickedButtonId()); if (!id.equals("")) { - if (!id.equals(currentAdvancementCategoryId)) { - // Send a packet indicating that we are opening this particular advancement window - ServerboundSeenAdvancementsPacket packet = new ServerboundSeenAdvancementsPacket(id); - session.sendDownstreamGamePacket(packet); - } + // Send a packet indicating that we are opening this particular advancement window + ServerboundSeenAdvancementsPacket packet = new ServerboundSeenAdvancementsPacket(id); + session.sendDownstreamGamePacket(packet); currentAdvancementCategoryId = id; buildAndShowListForm(); } @@ -188,6 +186,10 @@ public class AdvancementsCache { .content(content) .button(GeyserLocale.getPlayerLocaleString("gui.back", language)) .validResultHandler((response) -> buildAndShowListForm()) + .closedResultHandler(() -> { + // Indicate that we have closed the current advancement tab + session.sendDownstreamGamePacket(new ServerboundSeenAdvancementsPacket()); + }) ); }