Adds some code for generating item icons

This commit is contained in:
Kristian Knarvik 2023-01-19 03:27:52 +01:00
parent 5bc251309a
commit e93a7cbe5b
7 changed files with 254 additions and 6 deletions

View File

@ -84,5 +84,11 @@
<version>1.19.3-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>19.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -11,11 +11,15 @@ import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* An abstract GUI used for creating specific GUIs
*/
@SuppressWarnings("unused")
public abstract class AbstractGUI {
private final UUID uuid;
private final Inventory inventory;
private final Map<Integer, Map<ClickType, GUIAction>> actions;
private UUID uuid;
private Inventory inventory;
private Map<Integer, Map<ClickType, GUIAction>> actions;
/**
* Instantiates a new abstract GUI
@ -25,12 +29,27 @@ public abstract class AbstractGUI {
* @param inventoryType <p>The type of inventory to use for the GUI, or null for a variable chest GUI</p>
*/
public AbstractGUI(int inventorySize, String inventoryName, InventoryType inventoryType) {
this.uuid = UUID.randomUUID();
Inventory inventory;
if (inventoryType == null) {
this.inventory = Bukkit.createInventory(null, inventorySize, inventoryName);
inventory = Bukkit.createInventory(null, inventorySize, inventoryName);
} else {
this.inventory = Bukkit.createInventory(null, inventoryType, inventoryName);
inventory = Bukkit.createInventory(null, inventoryType, inventoryName);
}
instantiate(inventory);
}
/**
* Instantiates a new abstract GUI
*
* @param inventory <p>The inventory to use for the GUI</p>
*/
public AbstractGUI(Inventory inventory) {
instantiate(inventory);
}
private void instantiate(Inventory inventory) {
this.uuid = UUID.randomUUID();
this.inventory = inventory;
this.actions = new HashMap<>();
GUIRegistry.registerGUI(this);
}

View File

@ -9,6 +9,7 @@ import java.util.function.BiConsumer;
/**
* A user-interface using an anvil GUI
*/
@SuppressWarnings("unused")
public abstract class AnvilGUI extends AbstractGUI {
private BiConsumer<String, Player> action;

View File

@ -11,6 +11,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
/**
* A listener for tracking GUI interaction
*/
@SuppressWarnings("unused")
public class GUIListener implements Listener {
private final boolean autoDelete;

View File

@ -0,0 +1,132 @@
package net.knarcraft.knargui.item;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.function.Consumer;
/**
* An abstract factory for creating GUI items
*
* @param <B> <p>A child class implementing this class</p>
*/
@SuppressWarnings("unused")
public abstract class AbstractGUIItemFactory<B extends AbstractGUIItemFactory<B>> {
private final ItemStack itemStack;
private B child;
/**
* Instantiates a new abstract GUI item factory
*
* @param itemStack <p>The item stack to use for this factory</p>
*/
protected AbstractGUIItemFactory(@NotNull ItemStack itemStack) {
this.itemStack = itemStack;
}
/**
* Sets the instance of the child class extending this class
*
* <p>This makes the factory return the given object. Setting this allows the factory to return a specific
* implementation every time, without using an unsafe cast.</p>
*
* @param child <p>The child class extending this</p>
*/
protected void setChild(B child) {
this.child = child;
}
/**
* Builds the item as described in previous calls
*
* @return <p>The output of this factory</p>
*/
public ItemStack build() {
return this.itemStack;
}
/**
* Sets the name of this factory's item
*
* @param name <p>The new item name</p>
* @return <p>The factory. Used for chaining commands</p>
*/
public B setName(String name) {
return changeItemMeta((meta) -> meta.setDisplayName(name));
}
/**
* Sets the lore for this factory's item
*
* @param lore <p>The new lore</p>
* @return <p>The factory. Used for chaining commands</p>
*/
public B setLore(List<String> lore) {
return changeItemMeta((meta) -> meta.setLore(lore));
}
/**
* Sets whether this factory's item should look enchanted
*
* @param enchanted <p>True if the item should look enchanted</p>
* @return <p>The factory. Used for chaining commands</p>
*/
public B setEnchanted(boolean enchanted) {
if (enchanted) {
changeItemMeta((meta) -> meta.addEnchant(Enchantment.MENDING, 1, true));
return changeItemMeta((meta) -> meta.addItemFlags(ItemFlag.HIDE_ENCHANTS));
} else {
//Remove all enchantments
changeItemMeta((meta) -> meta.removeEnchant(Enchantment.MENDING));
return changeItemMeta((meta) -> meta.removeItemFlags(ItemFlag.HIDE_ENCHANTS));
}
}
/**
* Changes some metadata for this factory's item
*
* @param action <p>The action to be run on the metadata</p>
* @return <p>The factory. Used for chaining commands</p>
*/
protected B changeItemMeta(Consumer<ItemMeta> action) {
return changeItemMeta(ItemMeta.class, action);
}
/**
* Changes some metadata for this factory's item
*
* @param metaType <p>The type of metadata to change</p>
* @param action <p>The action to be run on the metadata</p>
* @param <M> <p>The type of the metadata</p>
* @return <p>The factory. Used for chaining commands</p>
*/
protected <M extends ItemMeta> B changeItemMeta(Class<M> metaType, Consumer<M> action) {
M meta = checkForNullMetadata(metaType);
action.accept(meta);
this.itemStack.setItemMeta(meta);
if (child == null) {
throw new IllegalStateException("Child class instance is not defined.");
}
return child;
}
/**
* Throws an exception if this factory's item has null metadata
*
* @return <p>The metadata for this factory's item</p>
*/
protected <M extends ItemMeta> M checkForNullMetadata(Class<M> metaType) {
M meta = metaType.cast(this.itemStack.getItemMeta());
if (meta == null) {
throw new IllegalArgumentException("Cannot change missing metadata");
} else {
return meta;
}
}
}

View File

@ -0,0 +1,33 @@
package net.knarcraft.knargui.item;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
/**
* A class for crating visual items for the GUI
*/
@SuppressWarnings("unused")
public class GUIItemFactory extends AbstractGUIItemFactory<GUIItemFactory> {
/**
* Instantiates a new item factory
*
* @param material <p>The material to use for the new item</p>
*/
public GUIItemFactory(Material material) {
super(new ItemStack(material, 1));
setChild(this);
}
/**
* Instantiates a new item factory
*
* @param material <p>The material to use for the new item</p>
* @param amount <p>The number of items to be displayed</p>
*/
public GUIItemFactory(Material material, int amount) {
super(new ItemStack(material, amount));
setChild(this);
}
}

View File

@ -0,0 +1,56 @@
package net.knarcraft.knargui.item;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.profile.PlayerProfile;
import java.util.UUID;
/**
* An item factory for generating player head-based icons
*/
@SuppressWarnings("unused")
public class PlayerHeadGUIItemFactory extends AbstractGUIItemFactory<PlayerHeadGUIItemFactory> {
/**
* Instantiates a player head gui item factory
*/
public PlayerHeadGUIItemFactory() {
super(new ItemStack(Material.PLAYER_HEAD, 1));
setChild(this);
}
/**
* Uses the head skin from the given player
*
* @param player <p>The player whose skin should be used</p>
* @return <p>The factory. Used for chaining commands</p>
*/
public PlayerHeadGUIItemFactory useSkin(OfflinePlayer player) {
return changeItemMeta(SkullMeta.class, (meta) -> meta.setOwningPlayer(player));
}
/**
* Uses the head skin from the given player profile
*
* @param playerProfile <p>The player profile whose skin should be used</p>
* @return <p>The factory. Used for chaining commands</p>
*/
public PlayerHeadGUIItemFactory useSkin(PlayerProfile playerProfile) {
return changeItemMeta(SkullMeta.class, (meta) -> meta.setOwnerProfile(playerProfile));
}
/**
* Uses the head skin from the given player UUID
*
* @param uuid <p>The UUID of the skin to use</p>
* @return <p>The factory. Used for chaining commands</p>
*/
public PlayerHeadGUIItemFactory useSkin(UUID uuid) {
return useSkin(Bukkit.getOfflinePlayer(uuid));
}
}