diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockMapping.java b/api/geyser/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockMapping.java index c868e100a..d2ccfade6 100644 --- a/api/geyser/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockMapping.java +++ b/api/geyser/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockMapping.java @@ -4,5 +4,5 @@ import java.util.Map; import org.checkerframework.checker.nullness.qual.NonNull; -public record CustomBlockMapping(@NonNull CustomBlockData data, @NonNull Map states) { +public record CustomBlockMapping(@NonNull CustomBlockData data, @NonNull Map states, @NonNull String javaIdentifier, @NonNull boolean overrideItem) { } diff --git a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java index 1de8772de..4beeff34f 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java @@ -106,6 +106,11 @@ public class BlockRegistries { */ public static final MappedRegistry> CUSTOM_BLOCK_STATE_OVERRIDES = MappedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new)); + /** + * A registry which stores clean Java Ids and the custom block it should be replaced with in the context of items. + */ + public static final SimpleMappedRegistry CUSTOM_BLOCK_ITEM_OVERRIDES = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new)); + /** * A registry which stores skin texture hashes to custom skull blocks. */ 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 d7d49ee81..90a1eeadb 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 @@ -222,7 +222,7 @@ public class MappingsReader_v1 extends MappingsReader { Map states = createCustomBlockStatesMap(identifier, stateKeys, defaultStates, onlyOverrideStates, customBlockData, blockPropertyTypeMaps.stateKeyStrings(), blockPropertyTypeMaps.stateKeyInts(), blockPropertyTypeMaps.stateKeyBools()); - return new CustomBlockMapping(customBlockData, states); + return new CustomBlockMapping(customBlockData, states, identifier, !onlyOverrideStates); } private List createCustomBlockPermutations(JsonNode node, String identifier, String name) { 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 a180935d6..1858006f9 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 @@ -1,6 +1,7 @@ package org.geysermc.geyser.registry.populator; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -39,6 +40,7 @@ public class CustomBlockRegistryPopulator { Set customBlockNames = new ObjectOpenHashSet<>(); Set customBlocks = new ObjectOpenHashSet<>(); Int2ObjectMap blockStateOverrides = new Int2ObjectOpenHashMap<>(); + Map customBlockItemOverrides = new HashMap<>(); GeyserImpl.getInstance().getEventBus().fire(new GeyserDefineCustomBlocksEvent() { @Override public void registerCustomBlock(@NonNull CustomBlockData customBlockData) { @@ -79,6 +81,9 @@ public class CustomBlockRegistryPopulator { MappingsConfigReader mappingsConfigReader = new MappingsConfigReader(); mappingsConfigReader.loadBlockMappingsFromJson((key, block) -> { customBlocks.add(block.data()); + if (block.overrideItem()) { + customBlockItemOverrides.put(block.javaIdentifier(), block.data()); + } block.states().forEach((javaIdentifier, customBlockState) -> { int id = BlockRegistries.JAVA_IDENTIFIERS.getOrDefault(javaIdentifier, -1); blockStateOverrides.put(id, customBlockState); @@ -90,6 +95,9 @@ public class CustomBlockRegistryPopulator { BlockRegistries.CUSTOM_BLOCK_STATE_OVERRIDES.set(blockStateOverrides); GeyserImpl.getInstance().getLogger().debug("Registered " + blockStateOverrides.size() + " custom block overrides."); + + BlockRegistries.CUSTOM_BLOCK_ITEM_OVERRIDES.set(customBlockItemOverrides); + GeyserImpl.getInstance().getLogger().debug("Registered " + customBlockItemOverrides.size() + " custom block item overrides."); } static void generateCustomBlockStates(CustomBlockData customBlock, List blockStates, List customExtBlockStates, int stateVersion) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java index 3a2a18d5a..7a8010484 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java @@ -188,8 +188,14 @@ public abstract class ItemTranslator { ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.getOrDefault(bedrockItem.getJavaId(), DEFAULT_TRANSLATOR); ItemData.Builder builder = itemStackTranslator.translateToBedrock(itemStack, bedrockItem, session.getItemMappings()); + if (bedrockItem.isBlock()) { - builder.blockRuntimeId(bedrockItem.getBedrockBlockId()); + CustomBlockData customBlockData = BlockRegistries.CUSTOM_BLOCK_ITEM_OVERRIDES.getOrDefault(bedrockItem.getJavaIdentifier(), null); + if (customBlockData != null) { + translateCustomBlock(customBlockData, session, builder); + } else { + builder.blockRuntimeId(bedrockItem.getBedrockBlockId()); + } } if (bedrockItem == session.getItemMappings().getStoredItems().playerHead()) { @@ -302,6 +308,12 @@ public abstract class ItemTranslator { .getItemMapping(javaId, itemStack.getNbt(), session.getItemMappings()); int itemId = mapping.getBedrockId(); + + CustomBlockData customBlockData = BlockRegistries.CUSTOM_BLOCK_ITEM_OVERRIDES.getOrDefault(mapping.getJavaIdentifier(), null); + if (customBlockData != null) { + itemId = session.getItemMappings().getCustomBlockItemIds().getInt(customBlockData); + } + if (mapping == session.getItemMappings().getStoredItems().playerHead()) { CustomSkull customSkull = getCustomSkull(session, itemStack.getNbt()); if (customSkull != null) { @@ -547,6 +559,16 @@ public abstract class ItemTranslator { } } + /** + * Translates a custom block override + */ + private static void translateCustomBlock(CustomBlockData customBlockData, GeyserSession session, ItemData.Builder builder) { + int itemId = session.getItemMappings().getCustomBlockItemIds().getInt(customBlockData); + int blockRuntimeId = session.getBlockMappings().getCustomBlockStateIds().getInt(customBlockData.defaultBlockState()); + builder.id(itemId); + builder.blockRuntimeId(blockRuntimeId); + } + private static CustomSkull getCustomSkull(GeyserSession session, CompoundTag nbt) { if (nbt != null && nbt.contains("SkullOwner")) { if (!(nbt.get("SkullOwner") instanceof CompoundTag skullOwner)) { @@ -577,6 +599,4 @@ public abstract class ItemTranslator { } } - // TODO: Add translator for generic custom blocks - }