From 627e533e9c8d7902e579709d1c212015afba7d39 Mon Sep 17 00:00:00 2001 From: unurled Date: Thu, 14 Mar 2024 21:28:49 +0100 Subject: [PATCH] entity type gui + command --- .../sr/commands/CommandManager.java | 2 + .../sr/commands/admin/EntityTypeCommand.java | 171 ++++++++++++++++++ .../sr/components/entity/EntityManager.java | 84 +++++++++ .../sr/components/entity/SREntityType.java | 165 +++++++++++++++++ .../sr/data/gson/ItemStackSerializer.java | 32 ++++ .../unurled/sacredrealms/sr/gui/BackItem.java | 26 +++ .../sacredrealms/sr/gui/ForwardItem.java | 27 +++ .../sr/gui/entitytype/EntityArmorItem.java | 51 ++++++ .../sr/gui/entitytype/EntityBehaviorItem.java | 46 +++++ .../sr/gui/entitytype/EntityExpItem.java | 46 +++++ .../sr/gui/entitytype/EntityItemDisplay.java | 46 +++++ .../sr/gui/entitytype/EntityLevelItem.java | 46 +++++ .../sr/gui/entitytype/EntityLootItem.java | 39 ++++ .../sr/gui/entitytype/EntityNameItem.java | 46 +++++ .../sr/gui/entitytype/EntityStatsItem.java | 52 ++++++ .../sr/gui/entitytype/EntityTypeGUI.java | 73 ++++++++ .../sr/gui/entitytype/EntityTypeItem.java | 58 ++++++ src/main/resources/plugin.yml | 5 + 18 files changed, 1015 insertions(+) create mode 100644 src/main/java/me/unurled/sacredrealms/sr/commands/admin/EntityTypeCommand.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/components/entity/SREntityType.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/data/gson/ItemStackSerializer.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/gui/BackItem.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/gui/ForwardItem.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityArmorItem.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityBehaviorItem.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityExpItem.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityItemDisplay.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityLevelItem.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityLootItem.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityNameItem.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityStatsItem.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityTypeGUI.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityTypeItem.java diff --git a/src/main/java/me/unurled/sacredrealms/sr/commands/CommandManager.java b/src/main/java/me/unurled/sacredrealms/sr/commands/CommandManager.java index 3824538..be98094 100644 --- a/src/main/java/me/unurled/sacredrealms/sr/commands/CommandManager.java +++ b/src/main/java/me/unurled/sacredrealms/sr/commands/CommandManager.java @@ -6,6 +6,7 @@ import java.lang.reflect.InvocationTargetException; import me.unurled.sacredrealms.sr.SR; import me.unurled.sacredrealms.sr.commands.admin.AttributeCommand; import me.unurled.sacredrealms.sr.commands.admin.ClientBuildCommand; +import me.unurled.sacredrealms.sr.commands.admin.EntityTypeCommand; import me.unurled.sacredrealms.sr.commands.admin.LevelCommand; import me.unurled.sacredrealms.sr.commands.player.ResetAdventureCommand; import me.unurled.sacredrealms.sr.managers.Manager; @@ -38,6 +39,7 @@ public class CommandManager extends Manager { registerCommand("attributes", AttributeCommand.class); registerCommand("clientbuild", ClientBuildCommand.class); registerCommand("level", LevelCommand.class); + registerCommand("entitytype", EntityTypeCommand.class); registerCommand("resetadventure", ResetAdventureCommand.class); } diff --git a/src/main/java/me/unurled/sacredrealms/sr/commands/admin/EntityTypeCommand.java b/src/main/java/me/unurled/sacredrealms/sr/commands/admin/EntityTypeCommand.java new file mode 100644 index 0000000..02e8450 --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/commands/admin/EntityTypeCommand.java @@ -0,0 +1,171 @@ +package me.unurled.sacredrealms.sr.commands.admin; + +import java.util.Arrays; +import java.util.List; +import me.unurled.sacredrealms.sr.components.entity.EntityManager; +import me.unurled.sacredrealms.sr.components.entity.SREntityType; +import me.unurled.sacredrealms.sr.gui.entitytype.EntityTypeGUI; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.xenondevs.invui.window.Window; + +public class EntityTypeCommand implements TabExecutor { + + /** + * Executes the given command, returning its success.
+ * If false is returned, then the "usage" plugin.yml entry for this command (if defined) will be + * sent to the player. + * + * @param sender Source of the command + * @param command Command which was executed + * @param label Alias of the command which was used + * @param args Passed command arguments + * @return true if a valid command, otherwise false + */ + @Override + public boolean onCommand( + @NotNull CommandSender sender, + @NotNull Command command, + @NotNull String label, + @NotNull String[] args) { + if (!sender.hasPermission("sr.entitytype")) { + sender.sendMessage("You do not have permission to use this command."); + return true; + } + + if (args.length == 0) { + sender.sendMessage("Usage: /entitytype "); + return true; + } + + switch (args[0].toLowerCase()) { + case "create": + if (args.length < 2) { + sender.sendMessage("Usage: /entitytype create "); + return true; + } + if (!(sender instanceof Player p)) { + sender.sendMessage("You must be a player to use this command."); + return true; + } + break; + case "delete": + if (args.length < 2) { + sender.sendMessage("Usage: /entitytype delete "); + return true; + } + break; + case "edit": + if (args.length < 2) { + sender.sendMessage("Usage: /entitytype edit "); + return true; + } + if (!(sender instanceof Player p)) { + sender.sendMessage("You must be a player to use this command."); + return true; + } + if (args.length < 3) { + EntityManager em = EntityManager.getInstance(EntityManager.class); + if (!em.getTypes().stream().map(SREntityType::getID).toList().contains(args[1])) { + sender.sendMessage("Invalid entity type."); + return true; + } + SREntityType type = em.getType(args[1]); + Window window = + Window.single() + .setViewer(p) + .setTitle(args[1]) + .setGui(EntityTypeGUI.createGui(type)) + .build(); + return true; + } + if (args.length < 4) { + sender.sendMessage( + "Usage: /entitytype edit "); + return true; + } + if (args[2].equalsIgnoreCase("type")) { + if (args.length < 5) { + sender.sendMessage("Usage: /entitytype edit type "); + return true; + } + try { + EntityType type = EntityType.valueOf(args[4]); + EntityManager em = EntityManager.getInstance(EntityManager.class); + try { + em.getType(args[1]).setType(type); + } catch (Exception e) { + sender.sendMessage("An error occurred while setting the entity type."); + return true; + } + } catch (IllegalArgumentException e) { + sender.sendMessage("Invalid entity type."); + return true; + } + } + break; + case "list": + if (!(sender instanceof Player p)) { + sender.sendMessage("You must be a player to use this command."); + return true; + } + Window window = + Window.single().setViewer(p).setTitle(args[1]).setGui(EntityTypeGUI.listGui()).build(); + window.open(); + break; + } + return true; + } + + /** + * Requests a list of possible completions for a command argument. + * + * @param sender Source of the command. For players tab-completing a command inside of a command + * block, this will be the player, not the command block. + * @param command Command which was executed + * @param label Alias of the command which was used + * @param args The arguments passed to the command, including final partial argument to be + * completed + * @return A List of possible completions for the final argument, or null to default to the + * command executor + */ + @Override + public @Nullable List onTabComplete( + @NotNull CommandSender sender, + @NotNull Command command, + @NotNull String label, + @NotNull String[] args) { + if (sender.hasPermission("sr.entitytype")) { + if (args.length == 1) { + return List.of("create", "delete", "edit", "list"); + } + if (args.length == 2) { + return EntityManager.getInstance(EntityManager.class).getTypes().stream() + .map(SREntityType::getID) + .toList(); + } + if (args.length == 3) { + if (args[0].equalsIgnoreCase("edit")) { + return List.of("type", "behavior", "loot", "item", "stats", "name", "level"); + } + } + if (args.length == 4) { + if (args[0].equalsIgnoreCase("edit")) { + if (args[2].equalsIgnoreCase("type")) { + return List.of( + Arrays.stream(EntityType.values()) + .filter(EntityType::isAlive) + .map(EntityType::name) + .toString()); + } + } + } + } + return null; + } +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/components/entity/EntityManager.java b/src/main/java/me/unurled/sacredrealms/sr/components/entity/EntityManager.java index d037abc..4a98641 100644 --- a/src/main/java/me/unurled/sacredrealms/sr/components/entity/EntityManager.java +++ b/src/main/java/me/unurled/sacredrealms/sr/components/entity/EntityManager.java @@ -1,13 +1,26 @@ package me.unurled.sacredrealms.sr.components.entity; +import static me.unurled.sacredrealms.sr.utils.Logger.error; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.UUID; +import me.unurled.sacredrealms.sr.data.DataHandler; +import me.unurled.sacredrealms.sr.data.DataManager; +import me.unurled.sacredrealms.sr.data.gson.ItemStackDeserializer; +import me.unurled.sacredrealms.sr.data.gson.ItemStackSerializer; +import me.unurled.sacredrealms.sr.data.gson.PotionEffectDeserializer; import me.unurled.sacredrealms.sr.managers.Manager; import org.bukkit.entity.Entity; import org.bukkit.entity.Mob; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntitySpawnEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -15,11 +28,67 @@ public class EntityManager extends Manager { @NotNull private final HashMap entities; + private final List types; + public EntityManager() { super(); + this.types = new ArrayList<>(); entities = new HashMap<>(); } + /** Load the data */ + @Override + public void loadData() { + // loads all types + DataManager dm = DataManager.getInstance(DataManager.class); + if (dm == null) { + error("DataManager is null, Can't load entity data."); + return; + } + DataHandler dh = dm.getDataHandler(); + if (dh == null) { + error("DataHandler is null, Can't load entity data."); + return; + } + + Gson gson = + new GsonBuilder() + .registerTypeAdapter(PotionEffect.class, new PotionEffectDeserializer()) + .registerTypeAdapter(ItemStack.class, new ItemStackDeserializer()) + .excludeFieldsWithoutExposeAnnotation() + .create(); + + dh.getKeysAll("sr.entities") + .forEach( + key -> { + SREntityType type = gson.fromJson(dh.get(key), SREntityType.class); + if (type != null) { + types.add(type); + } + }); + } + + public void saveType(@NotNull SREntityType type) { + // save type + DataManager dm = DataManager.getInstance(DataManager.class); + if (dm == null) { + error("DataManager is null, Can't save entity data."); + return; + } + DataHandler dh = dm.getDataHandler(); + if (dh == null) { + error("DataHandler is null, Can't save entity data."); + return; + } + Gson gson = + new GsonBuilder() + .registerTypeAdapter(PotionEffect.class, new PotionEffectDeserializer()) + .registerTypeAdapter(ItemStack.class, new ItemStackSerializer()) + .excludeFieldsWithoutExposeAnnotation() + .create(); + dh.set("sr.entities." + type.getID(), gson.toJson(type)); + } + @Nullable public SREntity getEntity(@NotNull UUID uuid) { return entities.get(uuid); @@ -37,6 +106,21 @@ public class EntityManager extends Manager { return entities.containsKey(uuid); } + public void addEntityType(@NotNull SREntityType type) { + types.add(type); + } + + public List getTypes() { + return types; + } + + public SREntityType getType(@NotNull String ID) { + for (SREntityType type : types) { + if (type.getID().equals(ID)) return type; + } + return null; + } + @EventHandler public void onEntitySpawn(@NotNull EntitySpawnEvent e) { if (e.getEntity() instanceof Player) return; diff --git a/src/main/java/me/unurled/sacredrealms/sr/components/entity/SREntityType.java b/src/main/java/me/unurled/sacredrealms/sr/components/entity/SREntityType.java new file mode 100644 index 0000000..a7d9451 --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/components/entity/SREntityType.java @@ -0,0 +1,165 @@ +package me.unurled.sacredrealms.sr.components.entity; + +import com.google.gson.annotations.Expose; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import me.unurled.sacredrealms.sr.components.attributes.Attribute; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; + +public class SREntityType { + + @Expose private final String ID; + @Expose private String name; + @Expose private Integer level = 1; + @Expose private Long experience = 0L; + @Expose private HashMap attributes = new HashMap<>(); + @Expose private List armor = new ArrayList<>(); + private HashMap> itemAttributes = new HashMap<>(); + @Expose private List potionEffects = new ArrayList<>(); + @Expose private HashMap lootTable = new HashMap<>(); + @Expose private EntityType type; + @Expose private ItemStack item; + @Expose private ItemStack handItem; + @Expose private ItemStack secondHandItem; + + public SREntityType(String name, String ID) { + this.name = name; + this.ID = ID; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getID() { + return ID; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public Long getExperience() { + return experience; + } + + public void setExperience(Long experience) { + this.experience = experience; + } + + public HashMap getAttributes() { + return attributes; + } + + public void setAttributes(HashMap attributes) { + this.attributes = attributes; + } + + public HashMap> getItemAttributes() { + return itemAttributes; + } + + public void setItemAttributes(HashMap> itemAttributes) { + this.itemAttributes = itemAttributes; + } + + public List getPotionEffects() { + return potionEffects; + } + + public void setPotionEffects(List potionEffects) { + this.potionEffects = potionEffects; + } + + public HashMap getLootTable() { + return lootTable; + } + + public void setLootTable(HashMap lootTable) { + this.lootTable = lootTable; + } + + public void setItemAttributes(Attribute attribute, ItemStack item, Double value) { + if (itemAttributes.containsKey(attribute)) { + itemAttributes.get(attribute).put(item, value); + } else { + HashMap map = new HashMap<>(); + map.put(item, value); + itemAttributes.put(attribute, map); + } + } + + public void removeItemAttributes(Attribute attribute, ItemStack item) { + if (itemAttributes.containsKey(attribute)) { + itemAttributes.get(attribute).remove(item); + } + } + + public Double getItemAttributes(Attribute attribute, ItemStack item) { + if (itemAttributes.containsKey(attribute)) { + return itemAttributes.get(attribute).get(item); + } + return null; + } + + public HashMap getItemAttributes(Attribute attribute) { + return itemAttributes.getOrDefault(attribute, new HashMap<>()); + } + + public Double getTotalItemAttribute(Attribute attribute) { + if (itemAttributes == null) itemAttributes = new HashMap<>(); + return itemAttributes.getOrDefault(attribute, new HashMap<>()).values().stream() + .reduce(0.0, Double::sum); + } + + public EntityType getType() { + return type; + } + + public void setType(EntityType type) { + this.type = type; + } + + public ItemStack getItem() { + return item; + } + + public void setItem(ItemStack item) { + this.item = item; + } + + public List getArmor() { + return armor; + } + + public void setArmor(List armor) { + this.armor = armor; + } + + public ItemStack getHandItem() { + return handItem; + } + + public void setHandItem(ItemStack handItem) { + this.handItem = handItem; + } + + public ItemStack getSecondHandItem() { + return secondHandItem; + } + + public void setSecondHandItem(ItemStack secondHandItem) { + this.secondHandItem = secondHandItem; + } +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/data/gson/ItemStackSerializer.java b/src/main/java/me/unurled/sacredrealms/sr/data/gson/ItemStackSerializer.java new file mode 100644 index 0000000..53e8774 --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/data/gson/ItemStackSerializer.java @@ -0,0 +1,32 @@ +package me.unurled.sacredrealms.sr.data.gson; + +import com.google.gson.JsonElement; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import java.lang.reflect.Type; +import java.util.Arrays; +import org.bukkit.inventory.ItemStack; + +public class ItemStackSerializer implements JsonSerializer { + + /** + * Gson invokes this call-back method during serialization when it encounters a field of the + * specified type. + * + *

In the implementation of this call-back method, you should consider invoking {@link + * JsonSerializationContext#serialize(Object, Type)} method to create JsonElements for any + * non-trivial field of the {@code src} object. However, you should never invoke it on the {@code + * src} object itself since that will cause an infinite loop (Gson will call your call-back method + * again). + * + * @param src the object that needs to be converted to Json. + * @param typeOfSrc the actual type (fully genericized version) of the source object. + * @param context + * @return a JsonElement corresponding to the specified object. + */ + @Override + public JsonElement serialize(ItemStack src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(Arrays.toString(src.serializeAsBytes())); + } +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/gui/BackItem.java b/src/main/java/me/unurled/sacredrealms/sr/gui/BackItem.java new file mode 100644 index 0000000..9354aa2 --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/gui/BackItem.java @@ -0,0 +1,26 @@ +package me.unurled.sacredrealms.sr.gui; + +import org.bukkit.Material; +import xyz.xenondevs.invui.gui.PagedGui; +import xyz.xenondevs.invui.item.ItemProvider; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.controlitem.PageItem; + +public class BackItem extends PageItem { + + public BackItem() { + super(false); + } + + @Override + public ItemProvider getItemProvider(PagedGui gui) { + ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); + builder + .setDisplayName("$7Previous Page") + .addLoreLines( + gui.hasPreviousPage() + ? "§7Go to page §e" + gui.getCurrentPage() + "§7/§e" + gui.getPageAmount() + : "§cYou can't go further back"); + return builder; + } +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/gui/ForwardItem.java b/src/main/java/me/unurled/sacredrealms/sr/gui/ForwardItem.java new file mode 100644 index 0000000..e26666f --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/gui/ForwardItem.java @@ -0,0 +1,27 @@ +package me.unurled.sacredrealms.sr.gui; + +import org.bukkit.Material; +import xyz.xenondevs.invui.gui.PagedGui; +import xyz.xenondevs.invui.item.ItemProvider; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.controlitem.PageItem; + +public class ForwardItem extends PageItem { + + public ForwardItem() { + super(true); + } + + @Override + public ItemProvider getItemProvider(PagedGui gui) { + ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); + builder + .setDisplayName("§7Next page") + .addLoreLines( + gui.hasNextPage() + ? "§7Go to page §e" + (gui.getCurrentPage() + 2) + "§7/§e" + gui.getPageAmount() + : "§cThere are no more pages"); + + return builder; + } +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityArmorItem.java b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityArmorItem.java new file mode 100644 index 0000000..5cf0791 --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityArmorItem.java @@ -0,0 +1,51 @@ +package me.unurled.sacredrealms.sr.gui.entitytype; + +import me.unurled.sacredrealms.sr.components.entity.SREntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.invui.item.Item; +import xyz.xenondevs.invui.item.ItemProvider; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.AbstractItem; +import xyz.xenondevs.invui.window.Window; + +public class EntityArmorItem extends AbstractItem { + + private final ItemStack stack; + + public EntityArmorItem(SREntityType type, int armorSlot) { + if (armorSlot == 4) { + stack = type.getHandItem(); + } else if (armorSlot == 5) { + stack = type.getSecondHandItem(); + } else { + stack = type.getArmor().get(armorSlot); + } + } + + /** + * Gets the {@link ItemProvider}. This method gets called every time a {@link Window} is notified + * ({@link #notifyWindows()}). + * + * @return The {@link ItemProvider} + */ + @Override + public ItemProvider getItemProvider() { + return new ItemBuilder(stack); + } + + /** + * A method called if the {@link ItemStack} associated to this {@link Item} has been clicked by a + * player. + * + * @param clickType The {@link ClickType} the {@link Player} performed. + * @param player The {@link Player} who clicked on the {@link ItemStack}. + * @param event The {@link InventoryClickEvent} associated with this click. + */ + @Override + public void handleClick( + @NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {} +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityBehaviorItem.java b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityBehaviorItem.java new file mode 100644 index 0000000..ef9f515 --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityBehaviorItem.java @@ -0,0 +1,46 @@ +package me.unurled.sacredrealms.sr.gui.entitytype; + +import me.unurled.sacredrealms.sr.components.entity.SREntityType; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.invui.item.Item; +import xyz.xenondevs.invui.item.ItemProvider; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.AbstractItem; +import xyz.xenondevs.invui.window.Window; + +public class EntityBehaviorItem extends AbstractItem { + + String behavior; + + public EntityBehaviorItem(SREntityType type) { + // behavior = type.getBehavior(); + } + + /** + * Gets the {@link ItemProvider}. This method gets called every time a {@link Window} is notified + * ({@link #notifyWindows()}). + * + * @return The {@link ItemProvider} + */ + @Override + public ItemProvider getItemProvider() { + return new ItemBuilder(Material.NETHERITE_SWORD).setDisplayName("Behavior: " + behavior); + } + + /** + * A method called if the {@link ItemStack} associated to this {@link Item} has been clicked by a + * player. + * + * @param clickType The {@link ClickType} the {@link Player} performed. + * @param player The {@link Player} who clicked on the {@link ItemStack}. + * @param event The {@link InventoryClickEvent} associated with this click. + */ + @Override + public void handleClick( + @NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {} +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityExpItem.java b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityExpItem.java new file mode 100644 index 0000000..3e526cd --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityExpItem.java @@ -0,0 +1,46 @@ +package me.unurled.sacredrealms.sr.gui.entitytype; + +import me.unurled.sacredrealms.sr.components.entity.SREntityType; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.invui.item.Item; +import xyz.xenondevs.invui.item.ItemProvider; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.AbstractItem; +import xyz.xenondevs.invui.window.Window; + +public class EntityExpItem extends AbstractItem { + + private final Long exp; + + public EntityExpItem(SREntityType type) { + exp = type.getExperience(); + } + + /** + * Gets the {@link ItemProvider}. This method gets called every time a {@link Window} is notified + * ({@link #notifyWindows()}). + * + * @return The {@link ItemProvider} + */ + @Override + public ItemProvider getItemProvider() { + return new ItemBuilder(Material.EXPERIENCE_BOTTLE).setDisplayName("Experience: " + exp); + } + + /** + * A method called if the {@link ItemStack} associated to this {@link Item} has been clicked by a + * player. + * + * @param clickType The {@link ClickType} the {@link Player} performed. + * @param player The {@link Player} who clicked on the {@link ItemStack}. + * @param event The {@link InventoryClickEvent} associated with this click. + */ + @Override + public void handleClick( + @NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {} +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityItemDisplay.java b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityItemDisplay.java new file mode 100644 index 0000000..cec24ad --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityItemDisplay.java @@ -0,0 +1,46 @@ +package me.unurled.sacredrealms.sr.gui.entitytype; + +import me.unurled.sacredrealms.sr.components.entity.SREntityType; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.invui.item.Item; +import xyz.xenondevs.invui.item.ItemProvider; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.AbstractItem; +import xyz.xenondevs.invui.window.Window; + +public class EntityItemDisplay extends AbstractItem { + + private final String name; + + public EntityItemDisplay(SREntityType type) { + name = type.getItem().getType().name(); + } + + /** + * Gets the {@link ItemProvider}. This method gets called every time a {@link Window} is notified + * ({@link #notifyWindows()}). + * + * @return The {@link ItemProvider} + */ + @Override + public ItemProvider getItemProvider() { + return new ItemBuilder(Material.CREEPER_SPAWN_EGG).setDisplayName("Item Display: " + name); + } + + /** + * A method called if the {@link ItemStack} associated to this {@link Item} has been clicked by a + * player. + * + * @param clickType The {@link ClickType} the {@link Player} performed. + * @param player The {@link Player} who clicked on the {@link ItemStack}. + * @param event The {@link InventoryClickEvent} associated with this click. + */ + @Override + public void handleClick( + @NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {} +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityLevelItem.java b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityLevelItem.java new file mode 100644 index 0000000..bf5fa89 --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityLevelItem.java @@ -0,0 +1,46 @@ +package me.unurled.sacredrealms.sr.gui.entitytype; + +import me.unurled.sacredrealms.sr.components.entity.SREntityType; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.invui.item.Item; +import xyz.xenondevs.invui.item.ItemProvider; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.AbstractItem; +import xyz.xenondevs.invui.window.Window; + +public class EntityLevelItem extends AbstractItem { + + private final int level; + + public EntityLevelItem(SREntityType type) { + level = type.getLevel(); + } + + /** + * Gets the {@link ItemProvider}. This method gets called every time a {@link Window} is notified + * ({@link #notifyWindows()}). + * + * @return The {@link ItemProvider} + */ + @Override + public ItemProvider getItemProvider() { + return new ItemBuilder(Material.DIAMOND).setDisplayName("Level: " + level); + } + + /** + * A method called if the {@link ItemStack} associated to this {@link Item} has been clicked by a + * player. + * + * @param clickType The {@link ClickType} the {@link Player} performed. + * @param player The {@link Player} who clicked on the {@link ItemStack}. + * @param event The {@link InventoryClickEvent} associated with this click. + */ + @Override + public void handleClick( + @NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {} +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityLootItem.java b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityLootItem.java new file mode 100644 index 0000000..0f845b3 --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityLootItem.java @@ -0,0 +1,39 @@ +package me.unurled.sacredrealms.sr.gui.entitytype; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.invui.item.Item; +import xyz.xenondevs.invui.item.ItemProvider; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.AbstractItem; +import xyz.xenondevs.invui.window.Window; + +public class EntityLootItem extends AbstractItem { + + /** + * Gets the {@link ItemProvider}. This method gets called every time a {@link Window} is notified + * ({@link #notifyWindows()}). + * + * @return The {@link ItemProvider} + */ + @Override + public ItemProvider getItemProvider() { + return new ItemBuilder(Material.SKELETON_SKULL).setDisplayName("Death Loot"); + } + + /** + * A method called if the {@link ItemStack} associated to this {@link Item} has been clicked by a + * player. + * + * @param clickType The {@link ClickType} the {@link Player} performed. + * @param player The {@link Player} who clicked on the {@link ItemStack}. + * @param event The {@link InventoryClickEvent} associated with this click. + */ + @Override + public void handleClick( + @NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {} +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityNameItem.java b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityNameItem.java new file mode 100644 index 0000000..b8c05bc --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityNameItem.java @@ -0,0 +1,46 @@ +package me.unurled.sacredrealms.sr.gui.entitytype; + +import me.unurled.sacredrealms.sr.components.entity.SREntityType; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.invui.item.Item; +import xyz.xenondevs.invui.item.ItemProvider; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.AbstractItem; +import xyz.xenondevs.invui.window.Window; + +public class EntityNameItem extends AbstractItem { + + private final String name; + + public EntityNameItem(SREntityType type) { + name = type.getName(); + } + + /** + * Gets the {@link ItemProvider}. This method gets called every time a {@link Window} is notified + * ({@link #notifyWindows()}). + * + * @return The {@link ItemProvider} + */ + @Override + public ItemProvider getItemProvider() { + return new ItemBuilder(Material.NAME_TAG).setDisplayName(name); + } + + /** + * A method called if the {@link ItemStack} associated to this {@link Item} has been clicked by a + * player. + * + * @param clickType The {@link ClickType} the {@link Player} performed. + * @param player The {@link Player} who clicked on the {@link ItemStack}. + * @param event The {@link InventoryClickEvent} associated with this click. + */ + @Override + public void handleClick( + @NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {} +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityStatsItem.java b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityStatsItem.java new file mode 100644 index 0000000..5173fd8 --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityStatsItem.java @@ -0,0 +1,52 @@ +package me.unurled.sacredrealms.sr.gui.entitytype; + +import java.util.HashMap; +import me.unurled.sacredrealms.sr.components.attributes.Attribute; +import me.unurled.sacredrealms.sr.components.entity.SREntityType; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.invui.item.Item; +import xyz.xenondevs.invui.item.ItemProvider; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.AbstractItem; +import xyz.xenondevs.invui.window.Window; + +public class EntityStatsItem extends AbstractItem { + + private final HashMap attributes; + + public EntityStatsItem(SREntityType type) { + attributes = type.getAttributes(); + } + + /** + * Gets the {@link ItemProvider}. This method gets called every time a {@link Window} is notified + * ({@link #notifyWindows()}). + * + * @return The {@link ItemProvider} + */ + @Override + public ItemProvider getItemProvider() { + ItemBuilder builder = new ItemBuilder(Material.APPLE).setDisplayName("Add Stats"); + for (Attribute attribute : attributes.keySet()) { + builder.addLoreLines(attribute.getName() + ": " + attributes.get(attribute)); + } + return builder; + } + + /** + * A method called if the {@link ItemStack} associated to this {@link Item} has been clicked by a + * player. + * + * @param clickType The {@link ClickType} the {@link Player} performed. + * @param player The {@link Player} who clicked on the {@link ItemStack}. + * @param event The {@link InventoryClickEvent} associated with this click. + */ + @Override + public void handleClick( + @NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {} +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityTypeGUI.java b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityTypeGUI.java new file mode 100644 index 0000000..ce3bd59 --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityTypeGUI.java @@ -0,0 +1,73 @@ +package me.unurled.sacredrealms.sr.gui.entitytype; + +import java.util.List; +import java.util.stream.Collectors; +import me.unurled.sacredrealms.sr.components.entity.EntityManager; +import me.unurled.sacredrealms.sr.components.entity.SREntityType; +import me.unurled.sacredrealms.sr.gui.BackItem; +import me.unurled.sacredrealms.sr.gui.ForwardItem; +import org.bukkit.Material; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.invui.gui.Gui; +import xyz.xenondevs.invui.gui.PagedGui; +import xyz.xenondevs.invui.gui.structure.Markers; +import xyz.xenondevs.invui.item.Item; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.SimpleItem; + +public class EntityTypeGUI { + public static @NotNull Gui listGui() { + EntityManager em = EntityManager.getInstance(EntityManager.class); + List items = + em.getTypes().stream() + .map(type -> new SimpleItem(new ItemBuilder(type.getItem()))) + .collect(Collectors.toList()); + + Gui gui = + PagedGui.items() + .setStructure( + "# # # # # # # # #", + "# X X X X X X X #", + "# X X X X X X X #", + "# X X X X X X X #", + "# # # < # > # # #") + .addIngredient('X', Markers.CONTENT_LIST_SLOT_HORIZONTAL) + .addIngredient('<', new BackItem()) + .addIngredient('>', new ForwardItem()) + .setContent(items) + .build(); + return gui; + } + + public static @NotNull Gui createGui(SREntityType type) { + + Item border = + new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName("§r")); + + Gui gui = + Gui.normal() + .setStructure( + "# # # # # # # # #", + "# T B O I S N L #", // Type, Behavior, lOot, Item display, Stats, Name, Level + "# X X X P X X X #", // exPerience + "# H C E B X M A #", // Helmet, Chestplate, lEgging, Boots, Main hand, second hAnd + "# # # # # # # # #") + .addIngredient('#', border) + .addIngredient('T', new EntityTypeItem(type)) + .addIngredient('B', new EntityBehaviorItem(type)) + .addIngredient('O', new EntityLootItem()) + .addIngredient('I', new EntityItemDisplay(type)) + .addIngredient('S', new EntityStatsItem(type)) + .addIngredient('N', new EntityNameItem(type)) + .addIngredient('L', new EntityLevelItem(type)) + .addIngredient('P', new EntityExpItem(type)) + .addIngredient('H', new EntityArmorItem(type, 0)) + .addIngredient('C', new EntityArmorItem(type, 1)) + .addIngredient('E', new EntityArmorItem(type, 2)) + .addIngredient('B', new EntityArmorItem(type, 3)) + .addIngredient('M', new EntityArmorItem(type, 4)) + .addIngredient('A', new EntityArmorItem(type, 5)) + .build(); + return gui; + } +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityTypeItem.java b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityTypeItem.java new file mode 100644 index 0000000..066b4de --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/gui/entitytype/EntityTypeItem.java @@ -0,0 +1,58 @@ +package me.unurled.sacredrealms.sr.gui.entitytype; + +import static me.unurled.sacredrealms.sr.utils.Component.comp; + +import me.unurled.sacredrealms.sr.components.entity.SREntityType; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.invui.item.Item; +import xyz.xenondevs.invui.item.ItemProvider; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.AbstractItem; +import xyz.xenondevs.invui.window.Window; + +public class EntityTypeItem extends AbstractItem { + + private final EntityType type; + + public EntityTypeItem(SREntityType type) { + this.type = type.getType(); + } + + /** + * Gets the {@link ItemProvider}. This method gets called every time a {@link Window} is notified + * ({@link #notifyWindows()}). + * + * @return The {@link ItemProvider} + */ + @Override + public ItemProvider getItemProvider() { + return new ItemBuilder(Material.ZOMBIE_SPAWN_EGG).setDisplayName(type.name()); + } + + /** + * A method called if the {@link ItemStack} associated to this {@link Item} has been clicked by a + * player. + * + * @param clickType The {@link ClickType} the {@link Player} performed. + * @param player The {@link Player} who clicked on the {@link ItemStack}. + * @param event The {@link InventoryClickEvent} associated with this click. + */ + @Override + public void handleClick( + @NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) { + player.closeInventory(); + player.sendMessage( + comp( + " entitytype edit " + + event.getView().title() + + "type")); + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 5d38551..dbd04a4 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -23,6 +23,9 @@ permissions: sr.level: default: op description: When the player has permission for the command /level + sr.entitytype: + default: op + description: When the player has permission for the command /entitytype sr.resetadventure: default: op description: When the player has permission for the command /resetadventure @@ -34,5 +37,7 @@ commands: description: Set the client build of the player. level: description: Set the level of the player. + entitytype: + description: Create a new entity type. resetadventure: description: Reset the adventure of the player \ No newline at end of file