From 7f85e909b8fb5be7299584f167ebdeb02714bf3e Mon Sep 17 00:00:00 2001 From: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Date: Sun, 12 Mar 2023 18:53:10 -0700 Subject: [PATCH] Extended collision boxes actually work Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../component/CustomBlockComponents.java | 9 -- .../java/org/geysermc/geyser/Constants.java | 1 - .../block/GeyserCustomBlockComponents.java | 15 ---- .../util/CustomBlockComponentsMapping.java | 33 ++++++++ .../mappings/util/CustomBlockMapping.java | 3 +- .../util/CustomBlockStateBuilderMapping.java | 35 ++++++++ .../util/CustomBlockStateMapping.java | 33 ++++++++ .../mappings/versions/MappingsReader_v1.java | 82 +++++++++++++------ .../CustomBlockRegistryPopulator.java | 33 +++----- 9 files changed, 168 insertions(+), 76 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockComponentsMapping.java create mode 100644 core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockStateBuilderMapping.java create mode 100644 core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockStateMapping.java diff --git a/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java b/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java index 40f4fa496..a903d1676 100644 --- a/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java +++ b/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java @@ -51,13 +51,6 @@ public interface CustomBlockComponents { */ BoxComponent collisionBox(); - /** - * Gets the extended collision box - * Places an invisible collision block above the block to prevent players from jumping on top of it, if defined - * @return The extended collision box. - */ - BoxComponent extendedCollisionBox(); - /** * Gets the display name component * Equivalent to "minecraft:display_name" @@ -160,8 +153,6 @@ public interface CustomBlockComponents { Builder collisionBox(BoxComponent collisionBox); - Builder extendedCollisionBox(BoxComponent extendedCollisionBox); - Builder displayName(String displayName); Builder geometry(String geometry); diff --git a/core/src/main/java/org/geysermc/geyser/Constants.java b/core/src/main/java/org/geysermc/geyser/Constants.java index a6336a0fc..8090d46d5 100644 --- a/core/src/main/java/org/geysermc/geyser/Constants.java +++ b/core/src/main/java/org/geysermc/geyser/Constants.java @@ -42,7 +42,6 @@ public final class Constants { static final String SAVED_REFRESH_TOKEN_FILE = "saved-refresh-tokens.json"; public static final String GEYSER_CUSTOM_NAMESPACE = "geyser_custom"; - public static final String GEYSER_NAMESPACE = "geyser"; public static final String MINECRAFT_SKIN_SERVER_URL = "https://textures.minecraft.net/texture/"; diff --git a/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java b/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java index f4ba5985c..c58d35fea 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java @@ -47,7 +47,6 @@ import java.util.Set; public class GeyserCustomBlockComponents implements CustomBlockComponents { BoxComponent selectionBox; BoxComponent collisionBox; - BoxComponent extendedCollisionBox; String displayName; String geometry; Map materialInstances; @@ -64,7 +63,6 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents { private GeyserCustomBlockComponents(CustomBlockComponentsBuilder builder) { this.selectionBox = builder.selectionBox; this.collisionBox = builder.collisionBox; - this.extendedCollisionBox = builder.extendedCollisionBox; this.displayName = builder.displayName; this.geometry = builder.geometry; if (builder.materialInstances.isEmpty()) { @@ -97,11 +95,6 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents { return collisionBox; } - @Override - public BoxComponent extendedCollisionBox() { - return extendedCollisionBox; - } - @Override public String displayName() { return displayName; @@ -165,7 +158,6 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents { public static class CustomBlockComponentsBuilder implements Builder { protected BoxComponent selectionBox; protected BoxComponent collisionBox; - protected BoxComponent extendedCollisionBox; protected String displayName; protected String geometry; protected final Object2ObjectMap materialInstances = new Object2ObjectOpenHashMap<>(); @@ -211,13 +203,6 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents { return this; } - @Override - public Builder extendedCollisionBox(BoxComponent extendedCollisionBox) { - validateBox(extendedCollisionBox); - this.extendedCollisionBox = extendedCollisionBox; - return this; - } - @Override public Builder displayName(String displayName) { this.displayName = displayName; diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockComponentsMapping.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockComponentsMapping.java new file mode 100644 index 000000000..0d32463dc --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockComponentsMapping.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019-2022 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.registry.mappings.util; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.api.block.custom.component.BoxComponent; +import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents; + +public record CustomBlockComponentsMapping(@NonNull CustomBlockComponents components, BoxComponent extendedCollisionBox) { +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockMapping.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockMapping.java index 259189826..7b857e4b9 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockMapping.java +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockMapping.java @@ -29,12 +29,11 @@ import java.util.Map; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.api.block.custom.CustomBlockData; -import org.geysermc.geyser.api.block.custom.CustomBlockState; /** * This class is used to store a custom block mappings, which contain all of the * data required to register a custom block that overrides a group of java block * states. */ -public record CustomBlockMapping(@NonNull CustomBlockData data, @NonNull Map states, @NonNull String javaIdentifier, boolean overrideItem) { +public record CustomBlockMapping(@NonNull CustomBlockData data, @NonNull Map states, @NonNull String javaIdentifier, boolean overrideItem) { } diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockStateBuilderMapping.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockStateBuilderMapping.java new file mode 100644 index 000000000..2b4eb7c5d --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockStateBuilderMapping.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019-2022 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.registry.mappings.util; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.api.block.custom.CustomBlockState; +import org.geysermc.geyser.api.block.custom.component.BoxComponent; + +import java.util.function.Function; + +public record CustomBlockStateBuilderMapping(@NonNull Function builder, BoxComponent extendedCollisionBox) { +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockStateMapping.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockStateMapping.java new file mode 100644 index 000000000..307948794 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/util/CustomBlockStateMapping.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019-2022 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.registry.mappings.util; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.api.block.custom.CustomBlockState; +import org.geysermc.geyser.api.block.custom.component.BoxComponent; + +public record CustomBlockStateMapping(@NonNull CustomBlockState state, BoxComponent extendedCollisionBox) { +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java index 2c399e50b..48d50afb6 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java @@ -44,7 +44,10 @@ import org.geysermc.geyser.level.block.GeyserCustomBlockComponents.CustomBlockCo import org.geysermc.geyser.level.block.GeyserCustomBlockData.CustomBlockDataBuilder; import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.registry.BlockRegistries; +import org.geysermc.geyser.registry.mappings.util.CustomBlockComponentsMapping; import org.geysermc.geyser.registry.mappings.util.CustomBlockMapping; +import org.geysermc.geyser.registry.mappings.util.CustomBlockStateBuilderMapping; +import org.geysermc.geyser.registry.mappings.util.CustomBlockStateMapping; import org.geysermc.geyser.translator.collision.BlockCollision; import org.geysermc.geyser.util.BlockUtils; import org.geysermc.geyser.util.MathUtils; @@ -194,13 +197,14 @@ public class MappingsReader_v1 extends MappingsReader { if (BlockRegistries.JAVA_IDENTIFIERS.get().containsKey(identifier)) { // There is only one Java block state to override + CustomBlockComponentsMapping componentsMapping = createCustomBlockComponentsMapping(node, identifier, name); CustomBlockData blockData = customBlockDataBuilder - .components(createCustomBlockComponents(node, identifier, name)) + .components(componentsMapping.components()) .build(); - return new CustomBlockMapping(blockData, Map.of(identifier, blockData.defaultBlockState()), identifier, !onlyOverrideStates); + return new CustomBlockMapping(blockData, Map.of(identifier, new CustomBlockStateMapping(blockData.defaultBlockState(), componentsMapping.extendedCollisionBox())), identifier, !onlyOverrideStates); } - Map componentsMap = new LinkedHashMap<>(); + Map componentsMap = new LinkedHashMap<>(); JsonNode stateOverrides = node.get("state_overrides"); if (stateOverrides != null && stateOverrides.isObject()) { @@ -212,7 +216,7 @@ public class MappingsReader_v1 extends MappingsReader { if (!BlockRegistries.JAVA_IDENTIFIERS.get().containsKey(state)) { throw new InvalidCustomMappingsFileException("Unknown Java block state: " + state + " for state_overrides."); } - componentsMap.put(state, createCustomBlockComponents(overrideEntry.getValue(), state, name)); + componentsMap.put(state, createCustomBlockComponentsMapping(overrideEntry.getValue(), state, name)); } } if (componentsMap.isEmpty() && onlyOverrideStates) { @@ -225,7 +229,7 @@ public class MappingsReader_v1 extends MappingsReader { .stream() .filter(s -> s.startsWith(identifier + "[")) .filter(Predicate.not(componentsMap::containsKey)) - .forEach(state -> componentsMap.put(state, createCustomBlockComponents(null, state, name))); + .forEach(state -> componentsMap.put(state, createCustomBlockComponentsMapping(null, state, name))); } if (componentsMap.isEmpty()) { @@ -235,20 +239,21 @@ public class MappingsReader_v1 extends MappingsReader { // We pass in the first state and just use the hitbox from that as the default // Each state will have its own so this is fine String firstState = componentsMap.keySet().iterator().next(); - customBlockDataBuilder.components(createCustomBlockComponents(node, firstState, name)); + CustomBlockComponentsMapping firstComponentsMapping = createCustomBlockComponentsMapping(node, firstState, name); + customBlockDataBuilder.components(firstComponentsMapping.components()); return createCustomBlockMapping(customBlockDataBuilder, componentsMap, identifier, !onlyOverrideStates); } - private CustomBlockMapping createCustomBlockMapping(CustomBlockData.Builder customBlockDataBuilder, Map componentsMap, String identifier, boolean overrideItem) { + private CustomBlockMapping createCustomBlockMapping(CustomBlockData.Builder customBlockDataBuilder, Map componentsMap, String identifier, boolean overrideItem) { Map> valuesMap = new Object2ObjectOpenHashMap<>(); List permutations = new ArrayList<>(); - Map> blockStateBuilders = new Object2ObjectOpenHashMap<>(); + Map blockStateBuilders = new Object2ObjectOpenHashMap<>(); // For each Java block state, extract the property values, create a CustomBlockPermutation, // and a CustomBlockState builder - for (Map.Entry entry : componentsMap.entrySet()) { + for (Map.Entry entry : componentsMap.entrySet()) { String state = entry.getKey(); String[] pairs = splitStateString(state); @@ -267,8 +272,8 @@ public class MappingsReader_v1 extends MappingsReader { blockStateBuilder = blockStateBuilder.andThen(builder -> builder.stringProperty(property, value)); } - permutations.add(new CustomBlockPermutation(entry.getValue(), String.join(" && ", conditions))); - blockStateBuilders.put(state, blockStateBuilder.andThen(CustomBlockState.Builder::build)); + permutations.add(new CustomBlockPermutation(entry.getValue().components(), String.join(" && ", conditions))); + blockStateBuilders.put(state, new CustomBlockStateBuilderMapping(blockStateBuilder.andThen(CustomBlockState.Builder::build), entry.getValue().extendedCollisionBox())); } valuesMap.forEach((key, value) -> customBlockDataBuilder.stringProperty(key, new ArrayList<>(value))); @@ -277,8 +282,8 @@ public class MappingsReader_v1 extends MappingsReader { .permutations(permutations) .build(); // Build CustomBlockStates for each Java block state we wish to override - Map states = blockStateBuilders.entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().apply(customBlockData.blockStateBuilder()))); + Map states = blockStateBuilders.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> new CustomBlockStateMapping(e.getValue().builder().apply(customBlockData.blockStateBuilder()), e.getValue().extendedCollisionBox()))); return new CustomBlockMapping(customBlockData, states, identifier, overrideItem); } @@ -290,19 +295,18 @@ public class MappingsReader_v1 extends MappingsReader { * @param name the name of the custom block * @return the {@link CustomBlockComponents} object */ - private CustomBlockComponents createCustomBlockComponents(JsonNode node, String stateKey, String name) { + private CustomBlockComponentsMapping createCustomBlockComponentsMapping(JsonNode node, String stateKey, String name) { // This is needed to find the correct selection box for the given block int id = BlockRegistries.JAVA_IDENTIFIERS.getOrDefault(stateKey, -1); - BoxComponent boxComponent = createBoxComponent(id, 0, 16, 0); - BoxComponent extendedBoxComponent = createBoxComponent(id, 16, 32, -16); + BoxComponent boxComponent = createBoxComponent(id); + BoxComponent extendedBoxComponent = createExtendedBoxComponent(id); CustomBlockComponents.Builder builder = new CustomBlockComponentsBuilder() .collisionBox(boxComponent) - .selectionBox(boxComponent) - .extendedCollisionBox(extendedBoxComponent); + .selectionBox(boxComponent); if (node == null) { // No other components were defined - return builder.build(); + return new CustomBlockComponentsMapping(builder.build(), extendedBoxComponent); } BoxComponent selectionBox = createBoxComponent(node.get("selection_box")); @@ -315,7 +319,7 @@ public class MappingsReader_v1 extends MappingsReader { } BoxComponent extendedCollisionBox = createBoxComponent(node.get("extended_collision_box")); if (extendedCollisionBox != null) { - builder.extendedCollisionBox(extendedCollisionBox); + extendedBoxComponent = extendedCollisionBox; } @@ -404,11 +408,11 @@ public class MappingsReader_v1 extends MappingsReader { builder.tags(tagsSet); } - return builder.build(); + return new CustomBlockComponentsMapping(builder.build(), extendedBoxComponent); } /** - * Creates a {@link BoxComponent} based on a Java block's collision + * Creates a {@link BoxComponent} based on a Java block's collision with provided bounds and offsets * @param javaId the block's Java ID * @param minHeight the minimum height of the box * @param maxHeight the maximum height of the box @@ -428,11 +432,6 @@ public class MappingsReader_v1 extends MappingsReader { float offsetY = (float) boundingBox.getSizeY() * 8; float offsetZ = (float) boundingBox.getSizeZ() * 8; - // Unfortunately we need to clamp the values here to an effective size of one block - // This is quite a pain for anything like fences, as the player can just jump over them - // One possible solution would be to create invisible blocks that we use only for collision box - // These could be placed above the block when a custom block exceeds this limit - // I am hopeful this will be extended slightly since the geometry of blocks can be 1.875^3 float cornerX = MathUtils.clamp((float) boundingBox.getMiddleX() * 16 - 8 - offsetX, -8, 8); float cornerY = MathUtils.clamp((float) boundingBox.getMiddleY() * 16 - offsetY, minHeight, maxHeight); float cornerZ = MathUtils.clamp((float) boundingBox.getMiddleZ() * 16 - 8 - offsetZ, -8, 8); @@ -444,6 +443,35 @@ public class MappingsReader_v1 extends MappingsReader { return new BoxComponent(cornerX, cornerY + heightTranslation, cornerZ, sizeX, sizeY + heightTranslation, sizeZ); } + /** + * Creates a {@link BoxComponent} based on a Java block's collision + * @param javaId the block's Java ID + * @return the {@link BoxComponent} + */ + private BoxComponent createBoxComponent(int javaId) { + return createBoxComponent(javaId, 0, 16, 0); + } + + /** + * Creates the {@link BoxComponent} for an extended collision box based on a Java block's collision + * @param javaId the block's Java ID + * @return the {@link BoxComponent} or null if the block's collision box would not exceed 16 y units + */ + private BoxComponent createExtendedBoxComponent(int javaId) { + BlockCollision blockCollision = BlockUtils.getCollision(javaId); + if (blockCollision == null) { + return null; + } + BoundingBox boundingBox = blockCollision.getBoundingBoxes()[0]; + float offsetY = (float) boundingBox.getSizeY() * 8; + float cornerY = (float) boundingBox.getMiddleY() * 16 - offsetY; + float sizeY = (float) boundingBox.getSizeY() * 16; + if (cornerY > 16 || sizeY > 16) { + return createBoxComponent(javaId, 16, 32, -16); + } + return null; + } + /** * Creates a {@link BoxComponent} from a JSON Node * @param node the JSON node diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java index cd0d13cbb..805513368 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java @@ -48,9 +48,6 @@ public class CustomBlockRegistryPopulator { Set customBlocks = new ObjectOpenHashSet<>(); Int2ObjectMap blockStateOverrides = new Int2ObjectOpenHashMap<>(); Map customBlockItemOverrides = new HashMap<>(); - Map> extendedCollisionBoxes = new HashMap<>(); - Map extendedCollisionBoxSet = new HashMap<>(); - int[] extendedCollisionIndex = {0}; GeyserImpl.getInstance().getEventBus().fire(new GeyserDefineCustomBlocksEvent() { @Override @@ -77,20 +74,6 @@ public class CustomBlockRegistryPopulator { throw new IllegalArgumentException("Custom block is unregistered. Name: " + customBlockState.name()); } CustomBlockState oldBlockState = blockStateOverrides.put(id, customBlockState); - BoxComponent extendedCollisionBox = customBlockState.block().components().extendedCollisionBox(); - if (extendedCollisionBox != null) { - CustomBlockData extendedCollisionBlock = extendedCollisionBoxSet.getOrDefault(extendedCollisionBox, null); - if (extendedCollisionBlock == null) { - extendedCollisionBlock = createExtendedCollisionBlock(extendedCollisionBox, extendedCollisionIndex[0]++); - extendedCollisionBoxes.put(extendedCollisionBlock, new HashSet<>(id)); - customBlocks.add(extendedCollisionBlock); - extendedCollisionBoxSet.put(extendedCollisionBox, extendedCollisionBlock); - } else { - Set existingJavaIds = extendedCollisionBoxes.getOrDefault(extendedCollisionBlock, new HashSet<>()); - existingJavaIds.add(id); - extendedCollisionBoxes.put(extendedCollisionBlock, existingJavaIds); - } - } if (oldBlockState != null) { GeyserImpl.getInstance().getLogger().debug("Duplicate block state override for Java Identifier: " + javaIdentifier + " Old override: " + oldBlockState.name() + " New override: " + customBlockState.name()); @@ -110,6 +93,9 @@ public class CustomBlockRegistryPopulator { customBlocks.add(customSkull.getCustomBlockData()); } + Map> extendedCollisionBoxes = new HashMap<>(); + Map extendedCollisionBoxSet = new HashMap<>(); + int[] extendedCollisionIndex = {0}; MappingsConfigReader mappingsConfigReader = new MappingsConfigReader(); mappingsConfigReader.loadBlockMappingsFromJson((key, block) -> { customBlocks.add(block.data()); @@ -118,13 +104,13 @@ public class CustomBlockRegistryPopulator { } block.states().forEach((javaIdentifier, customBlockState) -> { int id = BlockRegistries.JAVA_IDENTIFIERS.getOrDefault(javaIdentifier, -1); - blockStateOverrides.put(id, customBlockState); - BoxComponent extendedCollisionBox = customBlockState.block().components().extendedCollisionBox(); + blockStateOverrides.put(id, customBlockState.state()); + BoxComponent extendedCollisionBox = customBlockState.extendedCollisionBox(); if (extendedCollisionBox != null) { CustomBlockData extendedCollisionBlock = extendedCollisionBoxSet.getOrDefault(extendedCollisionBox, null); if (extendedCollisionBlock == null) { extendedCollisionBlock = createExtendedCollisionBlock(extendedCollisionBox, extendedCollisionIndex[0]++); - extendedCollisionBoxes.put(extendedCollisionBlock, new HashSet<>(id)); + extendedCollisionBoxes.computeIfAbsent(extendedCollisionBlock, k -> new HashSet<>()).add(id); customBlocks.add(extendedCollisionBlock); extendedCollisionBoxSet.put(extendedCollisionBox, extendedCollisionBlock); } else { @@ -375,11 +361,14 @@ public class CustomBlockRegistryPopulator { private static CustomBlockData createExtendedCollisionBlock(BoxComponent boxComponent, int extendedCollisionBlock) { CustomBlockData customBlockData = new CustomBlockDataBuilder() - .name(Constants.GEYSER_NAMESPACE + ":extended_collision_" + extendedCollisionBlock) + .name("extended_collision_" + extendedCollisionBlock) .components( new CustomBlockComponentsBuilder() .collisionBox(boxComponent) - .selectionBox(new BoxComponent(0, 0, 0, 0, 0, 0)) + .selectionBox(BoxComponent.EMPTY_BOX) + .materialInstance("*", new MaterialInstance("glass", "alpha_test", false, false)) + .lightDampening(0) + .geometry("geometry.invisible") .build()) .build(); return customBlockData;