Configurable GUIs - hamza-cskn/obliviate-invs GitHub Wiki
Beggining to use configurable GUIs
ObliviateInvs can manage your YAML configuration files to load GUIs. It is super useful for creating user-friendly plugins. Just to let you know, that carrying GUI codes to configuration files comes with some issues and restrictions. Because you have to support complex items like fireworks, books, etc. Also, your icons may need complex behavior and graphics.
ObliviateInvs solves these issues and breaks these restrictions. Also, we provided rich configuration stuff that came to our mind.
TL;DR
Copy the code blocks in steps 1,2,3.
Step 1
Specify your menu configuration section/file to the API.
It's called a 'default table' because you can specify different configuration files for each GUI.
public class Test extends JavaPlugin {
@Override
public void onEnable() {
new InventoryAPI(this).init();
ConfigurableGuiCache.resetCaches(); //not obligatory but recommended at configuration reload methods.
GuiConfigurationTable.setDefaultConfigurationTable(new GuiConfigurationTable(getConfig()));
}
}
Step 2
Extend ConfigurableGui class. This class extends the Gui class. You cannot set the title and size of configurable GUIs in the constructor. These attributes are automatically set on init. If you want to override them, you can use setTitle, setSize methods after super() call.
The second parameter is the id of the GUI. This id will be used in configuration sections. If you want to change the section name but you don't want to change id of the GUI, then override getSectionPath() method.
public class ConfigurableTestGUI extends ConfigurableGui {
public ConfigurableTestGUI(Player player) {
super(player, "example-configurable-gui");
}
}
Step 3
Put icons on your GUI. Icons are split into two. Functional and Dysfunctional.
Dysfunctional icons are completely configuration file based and independent of any extra in-build code. You can add custom dysfunctional icons only using the config. For example, filler items.
Functional icons are executable icons. You must program these icons in-build.
Note: ObliviateInvs caches serialized itemstacks as itemstack (not as configuration section). Feel relaxed about using getIcon()
or addConfigIcon()
methods very often.
Passing names of functional icons is not required but if you don't, obliviate-invs will put these icons as dysfunctional until your addConfigIcon method overrides them. If you do not put the functional icons in some cases, this behavior may cause some misunderstanding for users.
Code
@Override
public void onOpen(InventoryOpenEvent event) {
putDysfunctionalIcons("functional-test-icon"); // passing functional icons' names are recommended
addConfigIcon("functional-test-icon").onClick(e -> {
player.sendMessage("You clicked");
});
}
Config
example-configurable-gui:
title: 'Custom Title'
row: 5
icons:
filler-item:
material: BLACK_STAINED_GLASS_PANE
display-name: '&a'
slot: 0-8
functional-test-icon:
material: DIAMOND_BOOTS
display-name: '&aGem'
slot: 4
enchantments:
- 'DEPTH_STRIDER:1'
item-flags:
#- 'HIDE_ENCHANTS'
- '*'
Minimal Configuration
You must specify the sections below in your config file.
example-configurable-gui:
title: 'Custom Title'
row: 5
icons:
functional-test-icon:
material: DIAMOND_BOOTS
slot: 4
Result
Also, you can get dysfunctional icons using:
List<DysfunctionalIcon> = super.getDysfunctionalIcons()
What Are GUI Configuration Tables
GUI Configuration Tables define your GUI config and their section names. For example, imagine that you want to make different configuration files for each gui thennnn you have to make different gui configuration tables for each gui. Also, GUI configuration files define section names too.
Defining custom config file to your GUI example
new MyConfigurableGui(player, "gui-id", new GuiConfigurationTable(getConfig())).open();
Default
example-configurable-gui:
title: 'Custom Title'
row: 5
icons:
functional-test-icon:
material: DIAMOND_BOOTS
slot: 4
new GuiConfigurationTable(myMenuConfig).setMaterialSectionName("type");
Changes the 'material' section name to 'type' for GUIs in myMenuConfig.
After the code above
example-configurable-gui:
title: 'Custom Title'
row: 5
icons:
functional-test-icon:
type: DIAMOND_BOOTS #<----
slot: 4
Manipluating Itemstacks At the Intermediate Of Put Process
Sometimes developers need to edit itemstacks before they are added to the GUI. For example, you may want to apply skin to player heads.
Example:
addConfigIcon("any-icon", item -> {
if (!(item.hasItemMeta() && item.getItemMeta() instanceof SkullMeta meta)) return item;
meta.setOwningPlayer(Bukkit.getOfflinePlayer(player.getUniqueId()));
item.setItemMeta(meta);
return item;
}).onClick(e -> {
//handle click event
});
Manual Deserializing ItemStacks
Sometimes you may need to deserialize itemstacks manually. obliviate-invs uses mc.obliviate.inventory.configurable.util.ItemStackSerializer.class
to deserialize.
Deserializing YAML Configuration To Item
ItemStack item = ItemStackSerializer.deserializeItemStack(section, guiConfigurationTable);
This method deserializes a configuration as an itemstack. This method parses item type, name, lore, amount, durability, enchantment, item flags, custom model data and unbreakability. However, this method does not parse placeholders because this type of itemstack must be raw to caching itemstacks and applying placeholders at runtime.
Placeholder Appling
PlaceholderUtil placeholderUtil = new PlaceholderUtil().add("{any_placeholder}", textValueOfThePlaceholder);
ItemStackSerializer.applyPlaceholdersToItemStack(item, placeholderUtil);
Serializing An Item To YAML Configuration
example-root-section:
item:
section
variable defines example-root-section.item
.
ItemStackSerializer.serializeItemStack(item, section);
After the code above
example-root-section:
item:
material: STONE
display-name: 'a stone'
Serializing Complex Item Datas
Some item stacks have complex metadata. For example; potions, banners, fireworks, enchanted books, written books, and skulls. ItemStack Serializer of obliviate-invs is not designed for these metadatas but it does a favor for developers. The serializer is called Bukkit's own serializer methods.
item1:
material: DIAMOND_CHESTPLATE
item2:
bukkit-serializing: true
item:
==: org.bukkit.inventory.ItemStack
type: ENCHANTED_BOOK
meta:
==: ItemMeta
meta-type: ENCHANTED
stored-enchants:
PROTECTION_PROJECTILE: 4
- item1 is a simple diamond chestplate. It doesn't have any metadata.
- item2 is an enchanted book. Enchantment books have custom NBTs for storing enchantments. So, the serializer is called Bukkit's serializer.
Gui Configuration Sections
title
Defines title text of the Gui.
title: 'Select a game to play'
row
Defines row amount of the GUI.
row: 5
slot
Defines slot of the icon. If the icon is a dysfunctional icon, you can specify multiple slot.
Examples:
slot: 5
Dysfunctional Icon only:
slot: 1,3,5
slot: 1-5
(represents 1,2,3,4,5)
material
Defines type of the icon
Examples:
material: STONE
display-name
Defines the name of the icon.
Examples:
display-name: 'Gem'
lore
Defines description of the icon.
Examples:
lore:
- 'line 1'
- 'line 2'
amount
Defines amount of the icon.
Examples:
amount: 5
enchantments
Defines enchantments of the icon. (supports enchanted books)
Examples:
enchantments:
- 'PROTECTION:2'
- 'UNBREAKING:5'
custom-model-data
Defines custom model data of the icon. (only supports 1.14+ servers)
Examples:
custom-model-data: 500
durability
defines durability/damage of the icon.
Examples:
durability: 30
unbreakable
Defines the icon is unbreakable or not. (only supports 1.11+ servers)
Examples:
unbreakable: true
item-flags
Defines item flags of the icon. You can hide additional informations from the item. '*' wildcard is allowed.
Examples:
item-flags:
- '*'
item-flags:
- 'HIDE_ENCHANTS'
glow
Defines the icon should glow or not. If the icon is enchanted glow section does not matter. This section adds an enchantment and hides using item flags.
Examples:
glow: true