Skip to content

Commit

Permalink
refactor: multiple unnamed creative item group is allowed
Browse files Browse the repository at this point in the history
  • Loading branch information
smartcmd committed Mar 2, 2025
1 parent 80f5122 commit 5e06702
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,25 @@
import java.util.Map;

/**
* Represents a category of creative items. A category in a collection of groups and some ungrouped items.
* Represents a category of creative items. A category is a collection of named and unnamed groups.
* Currently, there are only four visible categories in the creative inventory, and they are {@code Construction},
* {@code Nature}, {@code Equipment}, and {@code Items}.
*
* @author daoge_cmd
*/
public interface CreativeItemCategory {
/**
* Get a specific group by name in this category.
* Get a specific group by index in this category.
*
* @param name the name of the group. If an empty string is passed, the default group will be returned.
* Translation key is supported here.
* @param index the index of the group.
*
* @return the group with the specified name, or the default group if the name is empty. {@code null} will be returned if the group does not exist.
* @return the group with the specified index. {@code null} will be returned if the group does not exist.
*/
CreativeItemGroup getGroup(@MayContainTrKey String name);
CreativeItemGroup getGroup(int index);

/**
* Register a new group in this category.
* Register a new named group in the category. See docs in {@link CreativeItemGroup} for more details
* about the difference between named and unnamed groups.
*
* @param name the name of the group, empty string is not allowed here. Translation key is supported.
* @param icon the icon of the group.
Expand All @@ -35,21 +35,20 @@ public interface CreativeItemCategory {
CreativeItemGroup registerGroup(@MayContainTrKey String name, ItemStack icon);

/**
* Get the default group in this category.
* Register a new unnamed group in the category. See docs in {@link CreativeItemGroup} for more details
* about the difference between named and unnamed groups.
*
* @return the default group.
* @return the registered group.
*/
default CreativeItemGroup getDefaultGroup() {
return getGroup("");
}
CreativeItemGroup registerUnnamedGroup();

/**
* Get all groups in this category.
*
* @return a map of all groups in this category.
*/
@UnmodifiableView
Map<String, CreativeItemGroup> getGroups();
Map<Integer, CreativeItemGroup> getGroups();

/**
* Get the type of this category.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@
import java.util.Map;

/**
* Represents a single creative item group, which can contain multiple items.
* It is collapsed by default, but can be expanded by clicking.
* Represents a single creative item group, which can contain multiple items. There
* are two types of group: named and unnamed.
* <p>
* Named group's name is not empty. It is folded by default and can be expanded by
* clicking. When the group is folded, the icon will be shown above the group.
* <p>
* Unnamed group's name is empty. The items are flatten and cannot be folded. Multiple
* unnamed groups is allowed and can between two named groups to separate them. The icon
* of unnamed group can only be air since it will never be shown.
*
* @author daoge_cmd
*/
Expand Down Expand Up @@ -58,4 +65,13 @@ public interface CreativeItemGroup {
* @return the category of this group.
*/
CreativeItemCategory getCategory();

/**
* Check if this group is an unnamed group
*
* @return {@code true} if this group is an unnamed group, {@code false} otherwise.
*/
default boolean isUnnamedGroup() {
return getName().isEmpty();
}
}
Binary file modified data/resources/creative_items.nbt
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package org.allaymc.server.item.creative;

import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import com.google.common.base.Preconditions;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import lombok.Getter;
import org.allaymc.api.item.ItemStack;
import org.allaymc.api.item.creative.CreativeItemCategory;
import org.allaymc.api.item.creative.CreativeItemGroup;
import org.allaymc.api.item.interfaces.ItemAirStack;

import java.util.Collections;
import java.util.Map;
Expand All @@ -17,28 +19,37 @@ public class AllayCreativeItemCategory implements CreativeItemCategory {
@Getter
protected final org.cloudburstmc.protocol.bedrock.data.inventory.CreativeItemCategory type;

protected Map<String, CreativeItemGroup> groups;
protected Map<Integer, CreativeItemGroup> groups;

public AllayCreativeItemCategory(AllayCreativeItemRegistry registry, org.cloudburstmc.protocol.bedrock.data.inventory.CreativeItemCategory type) {
this.registry = registry;
this.type = type;
this.groups = new Object2ObjectOpenHashMap<>();
this.groups = new Int2ObjectOpenHashMap<>();
}

@Override
public CreativeItemGroup getGroup(String name) {
return groups.get(name);
public CreativeItemGroup getGroup(int index) {
return groups.get(index);
}

@Override
public CreativeItemGroup registerGroup(String name, ItemStack icon) {
Preconditions.checkNotNull(name);
Preconditions.checkNotNull(icon);
var group = new AllayCreativeItemGroup(registry, this, name, icon);
groups.put(name, group);
groups.put(group.getIndex(), group);
return group;
}

@Override
public Map<String, CreativeItemGroup> getGroups() {
public CreativeItemGroup registerUnnamedGroup() {
var group = new AllayCreativeItemGroup(registry, this, "", ItemAirStack.AIR_STACK);
groups.put(group.getIndex(), group);
return group;
}

@Override
public Map<Integer, CreativeItemGroup> getGroups() {
return Collections.unmodifiableMap(groups);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import org.allaymc.api.item.creative.CreativeItemGroup;
import org.allaymc.api.item.creative.CreativeItemRegistry;
import org.allaymc.api.item.initinfo.ItemStackInitInfo;
import org.allaymc.api.item.type.ItemTypes;
import org.allaymc.api.registry.Registries;
import org.allaymc.api.utils.Identifier;
import org.allaymc.api.utils.Utils;
Expand Down Expand Up @@ -59,18 +58,15 @@ protected void load() {
JsonParser.parseReader(reader).getAsJsonArray().forEach(entry -> {
var group = entry.getAsJsonObject();
var category = getCategory(CreativeItemCategory.valueOf(group.get("category").getAsString().toUpperCase()));

ItemStack iconItemStack;
if (group.has("icon")) {
var name = group.get("name").getAsString();
if (name.isEmpty()) {
category.registerUnnamedGroup();
} else {
var iconItemTypeName = new Identifier(group.get("icon").getAsString());
var iconItemType = Registries.ITEMS.get(iconItemTypeName);
Objects.requireNonNull(iconItemType, "Unknown icon item type: " + iconItemTypeName);
iconItemStack = iconItemType.createItemStack();
} else {
iconItemStack = ItemTypes.AIR.createItemStack();
category.registerGroup(name, iconItemType.createItemStack());
}

category.registerGroup(group.get("name").getAsString(), iconItemStack);
});
}

Expand All @@ -89,12 +85,13 @@ protected void load() {
.extraTag(item.getCompound("tag", NbtMap.builder().build()))
.autoAssignStackNetworkId(false).build()
);
var groupName = item.getString("group");
var group = category.getGroup(groupName);
int groupIndex = (int) item.getLong("groupIndex");
var group = category.getGroup(groupIndex);
if (group == null) {
log.warn("Unknown group {} for item {} in category {}!", groupName, itemTypeName, category.getType());
group = category.getDefaultGroup();
log.warn("Unknown group index {} for item {} in category {}!", groupIndex, itemTypeName, category.getType());
continue;
}

group.registerItem(itemStack);
}
}
Expand Down

0 comments on commit 5e06702

Please sign in to comment.