From e2bc392a908f19822aebbbc87b062975d0e8ca8c Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 4 Jun 2023 14:11:42 +0200 Subject: [PATCH] [Feature] API to simplify generation of Creative-Tabs --- .../complexmaterials/ComplexMaterial.java | 26 +++++ .../bclib/creativetab/BCLCreativeTab.java | 97 +++++++++++++++++++ .../creativetab/BCLCreativeTabManager.java | 79 +++++++++++++++ 3 files changed, 202 insertions(+) create mode 100644 src/main/java/org/betterx/bclib/creativetab/BCLCreativeTab.java create mode 100644 src/main/java/org/betterx/bclib/creativetab/BCLCreativeTabManager.java diff --git a/src/main/java/org/betterx/bclib/complexmaterials/ComplexMaterial.java b/src/main/java/org/betterx/bclib/complexmaterials/ComplexMaterial.java index 6848cddc..02217dd5 100644 --- a/src/main/java/org/betterx/bclib/complexmaterials/ComplexMaterial.java +++ b/src/main/java/org/betterx/bclib/complexmaterials/ComplexMaterial.java @@ -10,6 +10,7 @@ import org.betterx.worlds.together.tag.v3.TagManager; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; +import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockBehaviour; @@ -209,6 +210,31 @@ public abstract class ComplexMaterial { return blocks.get(key.suffix); } + /** + * Get initiated {@link Block} from this {@link ComplexMaterial}. + * + * @param key {@link MaterialSlot} The Block Entry + * @param The {@link ComplexMaterial} this slot is usable for Type + * @return {@link Block} or {@code null} if nothing is stored. + */ + @Nullable + public BlockItem getBlockItem(MaterialSlot key) { + return getBlockItem(key.suffix); + } + + /** + * Get initiated {@link Block} from this {@link ComplexMaterial}. + * + * @param key {@link MaterialSlot} The Block Entry + * @param The {@link ComplexMaterial} this slot is usable for Type + * @return {@link Block} or {@code null} if nothing is stored. + */ + @Nullable + public BlockItem getBlockItem(String key) { + final Block bl = blocks.get(key); + return bl != null && bl.asItem() instanceof BlockItem bi ? bi : null; + } + /** * Get initiated {@link Item} from this {@link ComplexMaterial}. * diff --git a/src/main/java/org/betterx/bclib/creativetab/BCLCreativeTab.java b/src/main/java/org/betterx/bclib/creativetab/BCLCreativeTab.java new file mode 100644 index 00000000..84ff72c9 --- /dev/null +++ b/src/main/java/org/betterx/bclib/creativetab/BCLCreativeTab.java @@ -0,0 +1,97 @@ +package org.betterx.bclib.creativetab; + +import org.betterx.bclib.behaviours.interfaces.*; + +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.ItemLike; + +import java.util.LinkedList; +import java.util.List; +import org.jetbrains.annotations.NotNull; + +public class BCLCreativeTab { + public static CreativeTabPredicate NATURE = item -> item instanceof BlockItem bi + && (bi.getBlock() instanceof BehaviourSapling + || bi.getBlock() instanceof BehaviourSeed + || bi.getBlock() instanceof BehaviourLeaves + || bi.getBlock() instanceof BehaviourPlant + || bi.getBlock() instanceof BehaviourWaterPlant + || bi.getBlock() instanceof BehaviourVine); + + public static CreativeTabPredicate BLOCKS = item -> item instanceof BlockItem; + + public interface CreativeTabPredicate { + boolean contains(Item item); + } + + public final ResourceLocation id; + public final ItemLike icon; + public final Component title; + public final CreativeTabPredicate predicate; + + public final ResourceKey key; + + public BCLCreativeTab(ResourceLocation id, ItemLike icon, Component title, CreativeTabPredicate predicate) { + this.id = id; + this.icon = icon; + this.title = title; + this.predicate = predicate; + this.key = ResourceKey.create( + Registries.CREATIVE_MODE_TAB, + id + ); + this.items = new LinkedList<>(); + } + + protected final List items; + + void addItem(Item item) { + items.add(item); + } + + public static class Builder { + private final String name; + private final ResourceLocation id; + private ItemLike icon; + private CreativeTabPredicate predicate = item -> true; + private Component title; + private final BCLCreativeTabManager manager; + + public Builder(@NotNull BCLCreativeTabManager manager, @NotNull String name) { + this.name = name; + this.manager = manager; + this.id = new ResourceLocation(manager.modID, name + "_tab"); + this.title = Component.translatable("itemGroup." + manager.modID + "." + name); + } + + public Builder setIcon(ItemLike icon) { + this.icon = icon; + return this; + } + + public Builder setPredicate(CreativeTabPredicate predicate) { + this.predicate = predicate; + return this; + } + + public Builder setTitle(Component title) { + this.title = title; + return this; + } + + public BCLCreativeTabManager build() { + if (icon == null) + throw new IllegalStateException("Icon must be set"); + BCLCreativeTab res = new BCLCreativeTab(id, icon, title, predicate); + manager.tabs.add(res); + + return manager; + } + } +} diff --git a/src/main/java/org/betterx/bclib/creativetab/BCLCreativeTabManager.java b/src/main/java/org/betterx/bclib/creativetab/BCLCreativeTabManager.java new file mode 100644 index 00000000..57a8e6c9 --- /dev/null +++ b/src/main/java/org/betterx/bclib/creativetab/BCLCreativeTabManager.java @@ -0,0 +1,79 @@ +package org.betterx.bclib.creativetab; + +import org.betterx.bclib.registry.BaseRegistry; + +import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ItemLike; + +import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; + +import java.util.LinkedList; +import java.util.List; + +public class BCLCreativeTabManager { + public final String modID; + protected final List tabs = new LinkedList<>(); + + public static BCLCreativeTabManager create(String modID) { + return new BCLCreativeTabManager(modID); + } + + protected BCLCreativeTabManager(String modID) { + this.modID = modID; + } + + public BCLCreativeTab.Builder createTab(String name) { + return new BCLCreativeTab.Builder(this, name); + } + + public BCLCreativeTab.Builder createBlockTab(ItemLike icon) { + return new BCLCreativeTab.Builder(this, "blocks").setIcon(icon).setPredicate(BCLCreativeTab.BLOCKS); + } + + public BCLCreativeTab.Builder createItemsTab(ItemLike icon) { + return new BCLCreativeTab.Builder(this, "items").setIcon(icon); + } + + public BCLCreativeTabManager processBCLRegistry() { + process(BaseRegistry.getModItems(modID)); + process(BaseRegistry.getModBlockItems(modID)); + return this; + } + + public BCLCreativeTabManager process(List items) { + for (Item item : items) { + for (BCLCreativeTab tab : tabs) { + if (tab.predicate.contains(item)) { + tab.addItem(item); + break; + } + } + } + + return this; + } + + public void register() { + for (BCLCreativeTab tab : tabs) { + var tabItem = FabricItemGroup + .builder() + .icon(() -> new ItemStack(tab.icon)) + .title(tab.title) + .displayItems((featureFlagSet, output) -> { + output.acceptAll(tab.items.stream().map(ItemStack::new).toList()); + tab.items.clear(); + }).build(); + + Registry.register( + BuiltInRegistries.CREATIVE_MODE_TAB, + tab.key, + tabItem + ); + } + + this.tabs.clear(); + } +}