From 280764504d43b8785a0e6c7ca841ba9b5c869677 Mon Sep 17 00:00:00 2001 From: Sky Date: Sun, 13 Feb 2022 18:31:04 +0100 Subject: [PATCH] :rocket: Abilities! --- .../itsthesky/itemcreator/ItemCreator.java | 50 +++++++ .../itemcreator/api/ItemCreatorAPI.java | 6 + .../itemcreator/api/abilities/Ability.java | 97 ++++++++++++++ .../api/abilities/DefaultParameters.java | 30 +++++ .../api/abilities/RawAbilityParameter.java | 24 ++++ .../api/abilities/RightClickAbility.java | 36 +++++ .../api/cooldown/CooldownManager.java | 115 ++++++++++++++++ .../api/properties/base/ItemProperty.java | 4 + .../api/properties/base/MenuProperty.java | 42 ++++++ .../itemcreator/core/CreatorCommand.java | 35 +++-- .../itemcreator/core/CustomItem.java | 72 ++++++++++ .../itemcreator/core/ItemCreatorAPIImpl.java | 33 +++++ .../itemcreator/core/ParameterImpl.java | 45 +++++++ .../itemcreator/core/abilities/ItemThrow.java | 67 ++++++++++ .../itemcreator/core/gui/EditorGUI.java | 37 +++--- .../itemcreator/core/gui/ItemListGUI.java | 1 - .../core/gui/abilities/AbilityListGUI.java | 124 ++++++++++++++++++ .../core/gui/abilities/ParametersListGUI.java | 94 +++++++++++++ .../core/properties/AbilitiesProperty.java | 38 ++++++ .../properties/events/CommandsProperty.java | 18 ++- .../itsthesky/itemcreator/utils/Utils.java | 6 +- 21 files changed, 942 insertions(+), 32 deletions(-) create mode 100644 src/main/java/info/itsthesky/itemcreator/api/abilities/Ability.java create mode 100644 src/main/java/info/itsthesky/itemcreator/api/abilities/DefaultParameters.java create mode 100644 src/main/java/info/itsthesky/itemcreator/api/abilities/RawAbilityParameter.java create mode 100644 src/main/java/info/itsthesky/itemcreator/api/abilities/RightClickAbility.java create mode 100644 src/main/java/info/itsthesky/itemcreator/api/cooldown/CooldownManager.java create mode 100644 src/main/java/info/itsthesky/itemcreator/api/properties/base/MenuProperty.java create mode 100644 src/main/java/info/itsthesky/itemcreator/core/ParameterImpl.java create mode 100644 src/main/java/info/itsthesky/itemcreator/core/abilities/ItemThrow.java create mode 100644 src/main/java/info/itsthesky/itemcreator/core/gui/abilities/AbilityListGUI.java create mode 100644 src/main/java/info/itsthesky/itemcreator/core/gui/abilities/ParametersListGUI.java create mode 100644 src/main/java/info/itsthesky/itemcreator/core/properties/AbilitiesProperty.java diff --git a/src/main/java/info/itsthesky/itemcreator/ItemCreator.java b/src/main/java/info/itsthesky/itemcreator/ItemCreator.java index 82e1539..49a0985 100644 --- a/src/main/java/info/itsthesky/itemcreator/ItemCreator.java +++ b/src/main/java/info/itsthesky/itemcreator/ItemCreator.java @@ -3,10 +3,15 @@ import de.leonhard.storage.Config; import fr.mrmicky.fastinv.FastInvManager; import info.itsthesky.itemcreator.api.ItemCreatorAPI; +import info.itsthesky.itemcreator.api.abilities.Ability; +import info.itsthesky.itemcreator.api.abilities.DefaultParameters; +import info.itsthesky.itemcreator.api.abilities.RawAbilityParameter; +import info.itsthesky.itemcreator.api.cooldown.CooldownManager; import info.itsthesky.itemcreator.api.properties.base.ItemProperty; import info.itsthesky.itemcreator.core.CreatorCommand; import info.itsthesky.itemcreator.core.ItemCreatorAPIImpl; import info.itsthesky.itemcreator.core.MainListener; +import info.itsthesky.itemcreator.core.abilities.ItemThrow; import info.itsthesky.itemcreator.core.langs.LangLoader; import info.itsthesky.itemcreator.core.properties.*; import info.itsthesky.itemcreator.core.properties.attributes.AttributeProperty; @@ -22,6 +27,7 @@ import info.itsthesky.itemcreator.core.properties.spawners.SpawnerTypeProperty; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.HashMap; @@ -30,7 +36,10 @@ public final class ItemCreator extends JavaPlugin { private static ItemCreator instance; private static Config config; + private static CooldownManager cooldownManager; private HashMap registeredProperties; + private HashMap registeredAbilities; + private HashMap registeredParameters; private ItemCreatorAPI api; private LangLoader langLoader; @@ -44,11 +53,21 @@ public void onEnable() { config = new Config(configFile); FastInvManager.register(this); + cooldownManager = new CooldownManager(this); instance = this; api = new ItemCreatorAPIImpl(this); langLoader = new LangLoader(this, config.getOrSetDefault("default_language", "en_US")); + getLogger().info("Registering parameters ..."); + registeredParameters = new HashMap<>(); + api.registerParameter(DefaultParameters.ABILITY_FORCE); + api.registerParameter(DefaultParameters.ABILITY_COOLDOWN); + + getLogger().info("Registering Abilities ..."); + registeredAbilities = new HashMap<>(); + api.registerAbility(new ItemThrow(this)); + getLogger().info("Registering Properties ..."); registeredProperties = new HashMap<>(); api.registerProperty(new ItemEnabled()); @@ -71,6 +90,7 @@ public void onEnable() { api.registerProperty(new PotionEffectsProperty()); api.registerProperty(new AttributeProperty()); api.registerProperty(new CommandsProperty(this)); + api.registerProperty(new AbilitiesProperty()); api.registerProperty(new CantCraftProperty()); api.registerProperty(new CantEnchantProperty()); @@ -103,6 +123,10 @@ public HashMap getRegisteredProperties() { return registeredProperties; } + public HashMap getRegisteredAbilities() { + return registeredAbilities; + } + @NotNull public static Config getConfiguration() { return config; @@ -116,4 +140,30 @@ public void onDisable() { public LangLoader getLangLoader() { return langLoader; } + + public @Nullable Ability getAbilityFromId(String id) { + return getRegisteredAbilities() + .values() + .stream() + .filter(ab -> ab.getId().equals(id)) + .findAny() + .orElse(null); + } + + public @Nullable RawAbilityParameter getParameterFromId(String id) { + return getRegisteredParameters() + .values() + .stream() + .filter(ab -> ab.getId().equals(id)) + .findAny() + .orElse(null); + } + + public static CooldownManager getCooldownManager() { + return cooldownManager; + } + + public HashMap getRegisteredParameters() { + return registeredParameters; + } } diff --git a/src/main/java/info/itsthesky/itemcreator/api/ItemCreatorAPI.java b/src/main/java/info/itsthesky/itemcreator/api/ItemCreatorAPI.java index 431dc13..6b8ef17 100644 --- a/src/main/java/info/itsthesky/itemcreator/api/ItemCreatorAPI.java +++ b/src/main/java/info/itsthesky/itemcreator/api/ItemCreatorAPI.java @@ -2,6 +2,8 @@ import de.leonhard.storage.Config; import info.itsthesky.itemcreator.ItemCreator; +import info.itsthesky.itemcreator.api.abilities.Ability; +import info.itsthesky.itemcreator.api.abilities.RawAbilityParameter; import info.itsthesky.itemcreator.api.properties.base.ItemProperty; import info.itsthesky.itemcreator.core.CustomItem; import org.bukkit.inventory.ItemStack; @@ -83,6 +85,10 @@ public interface ItemCreatorAPI { */ void registerProperty(ItemProperty property); + void registerAbility(Ability ability); + + void registerParameter(RawAbilityParameter parameter); + @NotNull File getItemFile(CustomItem item); @NotNull File getItemsFolder(); diff --git a/src/main/java/info/itsthesky/itemcreator/api/abilities/Ability.java b/src/main/java/info/itsthesky/itemcreator/api/abilities/Ability.java new file mode 100644 index 0000000..762b1b8 --- /dev/null +++ b/src/main/java/info/itsthesky/itemcreator/api/abilities/Ability.java @@ -0,0 +1,97 @@ +package info.itsthesky.itemcreator.api.abilities; + +import com.cryptomorin.xseries.XMaterial; +import de.leonhard.storage.Config; +import info.itsthesky.itemcreator.ItemCreator; +import info.itsthesky.itemcreator.api.ISnowflake; +import info.itsthesky.itemcreator.api.cooldown.CooldownManager; +import info.itsthesky.itemcreator.core.CustomItem; +import info.itsthesky.itemcreator.core.GUIRepresentation; +import info.itsthesky.itemcreator.core.langs.LangLoader; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.Listener; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; + +public abstract class Ability implements Listener, ISnowflake { + + public void onGenericEvent(@NotNull E event) { + if (!validate(event)) + return; + final Player player = getPlayer(event); + final CustomItem item = getItem(event); + if (item == null) + return; + if (ItemCreator.getCooldownManager().isOnCooldown(player.getUniqueId(), "ability_" + getId())) { + player.sendMessage(LangLoader.get().format("messages.ability_on_cooldown", ItemCreator.getCooldownManager().getUserCooldown(player.getUniqueId(), "ability_" + getId()) / 20)); + return; + } + ItemCreator.getCooldownManager().setUserCooldown(player.getUniqueId(), "ability_" + getId(), TimeUnit.SECONDS, getCooldown(item)); + launch(event, item, Stream.of(item.getAbilities().get(getId())) + .map(para -> new AbilityParameter(para.getParameter().parse(para.getValue().toString(), null), para.getParameter())).toArray(AbilityParameter[]::new)); + }; + + public abstract @Nullable CustomItem getItem(E event); + + public abstract @NotNull Player getPlayer(E event); + + public abstract boolean validate(E event); + + public abstract XMaterial getMaterial(); + + public abstract @NotNull RawAbilityParameter[] getParameters(); + + public abstract void launch(@NotNull E event, + @Nullable CustomItem item, + @NotNull AbilityParameter[] parameters); + + public boolean hasCooldown() { + return Arrays.stream(getParameters()).anyMatch(para -> para.getId().equals(DefaultParameters.ABILITY_COOLDOWN.getId())); + } + + public @NotNull Integer getCooldown(final CustomItem item) { + if (!hasCooldown()) + return 0; + return DefaultParameters.ABILITY_COOLDOWN.parse( + Stream.of(item.getAbilityParameters(this)) + .filter(para -> para.getParameter().getId().equals(DefaultParameters.ABILITY_COOLDOWN.getId())) + .map(AbilityParameter::getValue) + .findAny() + .orElse("0") + .toString(), null).intValue(); + } + + public GUIRepresentation getRepresentation() { + return new GUIRepresentation(getMaterial(), "abilities." + getId() + ".name", "abilities." + getId() + ".lore"); + } + + public AbilityParameter getParameterValue(RawAbilityParameter raw, CustomItem item) { + final Config config = ItemCreator.getInstance().getApi().getItemConfig(item); + final T value = config.getOrSetDefault("abilities." + getId() + "." + raw.getId(), raw.getDefaultValue()); + return new AbilityParameter<>(value, raw); + } + + public static class AbilityParameter { + + private final T value; + private final RawAbilityParameter parameter; + + public AbilityParameter(T value, RawAbilityParameter parameter) { + this.value = value; + this.parameter = parameter; + } + + public T getValue() { + return value; + } + + public RawAbilityParameter getParameter() { + return parameter; + } + } +} diff --git a/src/main/java/info/itsthesky/itemcreator/api/abilities/DefaultParameters.java b/src/main/java/info/itsthesky/itemcreator/api/abilities/DefaultParameters.java new file mode 100644 index 0000000..2797ba1 --- /dev/null +++ b/src/main/java/info/itsthesky/itemcreator/api/abilities/DefaultParameters.java @@ -0,0 +1,30 @@ +package info.itsthesky.itemcreator.api.abilities; + +import com.cryptomorin.xseries.XMaterial; +import info.itsthesky.itemcreator.core.ParameterImpl; +import info.itsthesky.itemcreator.core.langs.LangLoader; +import org.bukkit.entity.Player; + +import java.util.Random; +import java.util.function.BiFunction; + +/** + * List of default ability parameters + */ +public final class DefaultParameters { + + private static final BiFunction INTEGER_PARSER = (input, player) -> { + try { + return Integer.parseInt(input); + } catch (Exception ex) { + player.sendMessage(LangLoader.get().format("messages.wrong_number")); + return null; + } + }; + + public static final RawAbilityParameter ABILITY_FORCE = + new ParameterImpl<>("ability_force", XMaterial.GOLDEN_SWORD, 2, INTEGER_PARSER); + public static final RawAbilityParameter ABILITY_COOLDOWN = + new ParameterImpl<>("ability_cooldown", XMaterial.CLOCK, 0, INTEGER_PARSER); + +} diff --git a/src/main/java/info/itsthesky/itemcreator/api/abilities/RawAbilityParameter.java b/src/main/java/info/itsthesky/itemcreator/api/abilities/RawAbilityParameter.java new file mode 100644 index 0000000..a0919e5 --- /dev/null +++ b/src/main/java/info/itsthesky/itemcreator/api/abilities/RawAbilityParameter.java @@ -0,0 +1,24 @@ +package info.itsthesky.itemcreator.api.abilities; + +import com.cryptomorin.xseries.XMaterial; +import info.itsthesky.itemcreator.api.ISnowflake; +import info.itsthesky.itemcreator.core.GUIRepresentation; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface RawAbilityParameter extends ISnowflake { + + XMaterial getMaterial(); + + default GUIRepresentation getRepresentation() { + return new GUIRepresentation(getMaterial(), + "abilities.parameters." + getId() + "name", + "abilities.parameters." + getId() + "lore"); + } + + T getDefaultValue(); + + T parse(@NotNull String input, @Nullable Player player); + +} diff --git a/src/main/java/info/itsthesky/itemcreator/api/abilities/RightClickAbility.java b/src/main/java/info/itsthesky/itemcreator/api/abilities/RightClickAbility.java new file mode 100644 index 0000000..85d7100 --- /dev/null +++ b/src/main/java/info/itsthesky/itemcreator/api/abilities/RightClickAbility.java @@ -0,0 +1,36 @@ +package info.itsthesky.itemcreator.api.abilities; + +import info.itsthesky.itemcreator.ItemCreator; +import info.itsthesky.itemcreator.core.CustomItem; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class RightClickAbility extends Ability { + + // Check https://spigotmc.org/threads/204644/ + @EventHandler(priority = EventPriority.HIGHEST) + public void onEvent(@NotNull PlayerInteractEvent event) { + onGenericEvent(event); + } + + @Override + public @Nullable CustomItem getItem(PlayerInteractEvent event) { + final ItemStack stack = event.getItem(); + if (stack == null || stack.getType().equals(Material.AIR)) + return null; + return ItemCreator.getInstance().getApi().convert(stack); + } + + @Override + public boolean validate(PlayerInteractEvent event) { + return event.getAction().equals(Action.RIGHT_CLICK_AIR) + || event.getAction().equals(Action.RIGHT_CLICK_BLOCK); + } + +} diff --git a/src/main/java/info/itsthesky/itemcreator/api/cooldown/CooldownManager.java b/src/main/java/info/itsthesky/itemcreator/api/cooldown/CooldownManager.java new file mode 100644 index 0000000..81b6def --- /dev/null +++ b/src/main/java/info/itsthesky/itemcreator/api/cooldown/CooldownManager.java @@ -0,0 +1,115 @@ +package info.itsthesky.itemcreator.api.cooldown; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.BiConsumer; + +public class CooldownManager { + + private JavaPlugin main; + + private HashMap> cooldowns = new HashMap<>(); + + private CooldownManager() {} + + public CooldownManager(JavaPlugin main) { + this.main = main; + Bukkit.getScheduler().scheduleSyncRepeatingTask(main, this::tick, 1, 1); + } + + void tick() { + Iterator> iterator; + Map.Entry cooldown; + + for (Map.Entry> playerEntry : cooldowns.entrySet()) { + Set> entrySet = playerEntry.getValue().entrySet(); + + iterator = entrySet.iterator(); + + while (iterator.hasNext()) { + cooldown = iterator.next(); + + double value = cooldown.getValue().decrementAndGet(); + + if (value <= 0) { + iterator.remove(); + } + } + } + } + + public boolean isOnCooldown(UUID uuid, String id) { + return getUserCooldown(uuid, id) > 0; + } + + public long getUserCooldown(UUID uuid, String id) { + HashMap userCooldowns = cooldowns.get(uuid); + + if (userCooldowns == null) { + return 0; + } + + if (userCooldowns.containsKey(id)) { + long cooldown = userCooldowns.get(id).get(); + + if (cooldown <= 0) { + userCooldowns.remove(id); + return 0; + } + + return cooldown; + } + + return 0; + } + + public boolean setUserCooldown(UUID player, String id, TimeUnit timeUnit, long cooldown) { + return setUserCooldown(player, id, timeUnit.toSeconds(cooldown) * 20); + } + + public boolean setUserCooldown(final UUID player, final String id, TimeUnit timeUnit, long cooldown, BiConsumer function) { + return setUserCooldown(player, id, timeUnit.toSeconds(cooldown) * 20, function); + } + + public boolean setUserCooldown(UUID player, String id, long cooldown, BiConsumer function) { + boolean success = setUserCooldown(player, id, cooldown); + + if (!success) { + return false; + } + + Bukkit.getScheduler().scheduleSyncDelayedTask(main, () -> function.accept(player, id), cooldown); + + return true; + } + + public boolean setUserCooldown(UUID player, String id, long cooldown) { + + HashMap userCooldowns = cooldowns.get(player); + + if (userCooldowns == null) { + HashMap newCooldowns = new HashMap<>(); + + cooldowns.put(player, newCooldowns); + userCooldowns = newCooldowns; + } + + userCooldowns.put(id, new AtomicLong(cooldown)); + + return true; + } + + // TODO: stop callbacks for cooldowns + public void resetUserCooldowns(UUID player) { + cooldowns.remove(player); + } + + public void resetAllCooldowns() { + cooldowns.clear(); + } + +} diff --git a/src/main/java/info/itsthesky/itemcreator/api/properties/base/ItemProperty.java b/src/main/java/info/itsthesky/itemcreator/api/properties/base/ItemProperty.java index 6f9e3c0..9a63138 100644 --- a/src/main/java/info/itsthesky/itemcreator/api/properties/base/ItemProperty.java +++ b/src/main/java/info/itsthesky/itemcreator/api/properties/base/ItemProperty.java @@ -53,6 +53,10 @@ public GUIRepresentation asRepresentation() { public abstract T getDefaultValue(); + public boolean isSavable() { + return true; + } + public T getValue(@NotNull Config itemFile) { return convert(itemFile.getString(getId()), null); } diff --git a/src/main/java/info/itsthesky/itemcreator/api/properties/base/MenuProperty.java b/src/main/java/info/itsthesky/itemcreator/api/properties/base/MenuProperty.java new file mode 100644 index 0000000..f1ad80e --- /dev/null +++ b/src/main/java/info/itsthesky/itemcreator/api/properties/base/MenuProperty.java @@ -0,0 +1,42 @@ +package info.itsthesky.itemcreator.api.properties.base; + +import info.itsthesky.itemcreator.core.CustomItem; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; + +public abstract class MenuProperty extends ItemProperty { + + @Override + public ItemStack apply(ItemStack item, Object value) { + return item; + } + + @Override + public boolean allowClearing() { + return false; + } + + @Override + public Object getDefaultValue() { + return null; + } + + @Override + public boolean isSavable() { + return false; + } + + public abstract void onClick(Player player, CustomItem item); + + @Override + public void onEditorClick(InventoryClickEvent e, CustomItem item) { + onClick((Player) e.getWhoClicked(), item); + } + + @Override + public @Nullable Void convert(String input, Player player) { + return null; + } +} diff --git a/src/main/java/info/itsthesky/itemcreator/core/CreatorCommand.java b/src/main/java/info/itsthesky/itemcreator/core/CreatorCommand.java index 47a103b..4405f41 100644 --- a/src/main/java/info/itsthesky/itemcreator/core/CreatorCommand.java +++ b/src/main/java/info/itsthesky/itemcreator/core/CreatorCommand.java @@ -1,10 +1,12 @@ package info.itsthesky.itemcreator.core; import info.itsthesky.itemcreator.ItemCreator; +import info.itsthesky.itemcreator.api.abilities.Ability; import info.itsthesky.itemcreator.api.properties.base.ItemProperty; import info.itsthesky.itemcreator.api.properties.base.MultipleItemProperty; import info.itsthesky.itemcreator.core.gui.EditorGUI; import info.itsthesky.itemcreator.core.gui.ItemListGUI; +import info.itsthesky.itemcreator.core.langs.LangLoader; import info.itsthesky.itemcreator.utils.Utils; import org.apache.commons.lang.WordUtils; import org.bukkit.Bukkit; @@ -26,10 +28,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; +import java.util.*; import java.util.stream.Collectors; public class CreatorCommand implements CommandExecutor, TabCompleter { @@ -52,6 +51,16 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command sender.sendMessage(Utils.colored("&cYou must provide the item's ID!")); return false; } + + int amount; + try { + amount = Integer.parseInt(args[3]); + } catch (Exception ex) { + amount = 1; + } + if (amount < 1) + amount = 1; + Player player = args.length == 2 ? ((Player) sender).getPlayer() : Bukkit .getOnlinePlayers() .stream() @@ -67,7 +76,9 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command return false; } sender.sendMessage(Utils.colored("&aGive complete!")); - player.getInventory().addItem(item.asItem()); + final ItemStack itemStack = item.asItem(); + itemStack.setAmount(amount); + player.getInventory().addItem(itemStack); return true; case "menu": if (!(sender instanceof Player)) { @@ -169,6 +180,14 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command Utils.beauty(attribute) + " &7(ID: "+attribute.name()+")")); return true; + case "abilities": + final Collection abilities = ItemCreator.getInstance().getRegisteredAbilities().values(); + sender.sendMessage(Utils.colored("&6List of Abilities &e("+ abilities.size() +")&6:")); + for (Ability ability : abilities) + sender.sendMessage(Utils.colored(" &6→ &e" + + LangLoader.get().format("abilities." + ability.getId() + ".name") + + " &7(ID: "+ability.getId()+")")); + return true; case "operations": sender.sendMessage(Utils.colored("&6List of Operations &e("+ AttributeModifier.Operation.values().length +")&6:")); for (AttributeModifier.Operation attribute : AttributeModifier.Operation.values()) @@ -202,9 +221,9 @@ public void sendHelp(CommandSender sender) { sender.sendMessage( Utils.colored("&1"), Utils.colored("&6/ic help &7- &eShow this help page"), - Utils.colored("&6/ic get &7- &eGet the specified custom item"), + Utils.colored("&6/ic get [player] [amount] &7- &eGet the specified custom item"), Utils.colored("&6/ic menu &7- &eOpen the main ItemCreator menu"), - Utils.colored("&6/ic list (enchantments|actions|potion_effects|entities|operations|attributes|slots) &7- &eList possible values of enumeration"), + Utils.colored("&6/ic list (enchantments|abilities|actions|potion_effects|entities|operations|attributes|slots) &7- &eList possible values of enumeration"), Utils.colored("&6/ic convert &7- &cBETA &eConvert the item you're holding into an ItemCreator item."), Utils.colored("&6/ic generate_default &7- &eGenerate the default items ItemCreator provide to see everything it can do."), Utils.colored("&1") @@ -229,7 +248,7 @@ public void sendHelp(CommandSender sender) { .collect(Collectors.toList())); break; case "list": - completions.addAll(Arrays.asList("enchantments", "actions", "potion_effects", "entities", "slots", "attributes", "operations")); + completions.addAll(Arrays.asList("enchantments", "actions", "potion_effects", "entities", "slots", "abilities", "attributes", "operations")); break; } } else if (args.length == 3) { diff --git a/src/main/java/info/itsthesky/itemcreator/core/CustomItem.java b/src/main/java/info/itsthesky/itemcreator/core/CustomItem.java index 3c8f6ea..b67d0a9 100644 --- a/src/main/java/info/itsthesky/itemcreator/core/CustomItem.java +++ b/src/main/java/info/itsthesky/itemcreator/core/CustomItem.java @@ -1,10 +1,13 @@ package info.itsthesky.itemcreator.core; import com.cryptomorin.xseries.XMaterial; +import de.leonhard.storage.Config; import de.tr7zw.changeme.nbtapi.NBTItem; import fr.mrmicky.fastinv.ItemBuilder; import info.itsthesky.itemcreator.ItemCreator; import info.itsthesky.itemcreator.api.ISnowflake; +import info.itsthesky.itemcreator.api.abilities.Ability; +import info.itsthesky.itemcreator.api.abilities.RawAbilityParameter; import info.itsthesky.itemcreator.api.properties.base.ItemProperty; import info.itsthesky.itemcreator.utils.Utils; import org.bukkit.entity.Player; @@ -15,6 +18,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * Represent a whole custom item from {@link info.itsthesky.itemcreator.ItemCreator}. @@ -26,10 +30,12 @@ public class CustomItem implements ISnowflake { private final String id; private final List properties; private final HashMap propertiesValue; + private final HashMap abilities; public CustomItem(final String id) { this.properties = new ArrayList<>(); this.propertiesValue = new HashMap<>(); + this.abilities = new HashMap<>(); this.id = id; } @@ -38,6 +44,40 @@ public void registerProperty(ItemProperty property) { properties.add(property); } + public void registerAbility(Ability ability) { + if (hasAbility(ability)) + return; + final List parameters = new ArrayList<>(); + for (RawAbilityParameter raw : ability.getParameters()) + parameters.add(new Ability.AbilityParameter<>(raw.getDefaultValue(), raw)); + abilities.put(ability.getId(), parameters.toArray(new Ability.AbilityParameter[0])); + saveAbilities(); + } + + public void registerAbility(Ability ability, Ability.AbilityParameter[] parameters) { + if (hasAbility(ability)) + return; + /* final List parameters = new ArrayList<>(); + for (RawAbilityParameter raw : ability.getParameters()) + parameters.add(new Ability.AbilityParameter<>(raw.getDefaultValue(), raw)); */ + abilities.put(ability.getId(), parameters); + saveAbilities(); + } + + public void setAbilityParameters(Ability ability, Ability.AbilityParameter[] parameters) { + abilities.put(ability.getId(), parameters); + saveAbilities(); + } + + public void saveAbilities() { + final Config config = ItemCreator.getInstance().getApi().getItemConfig(this); + abilities.forEach((id, parameters) -> { + config.set("abilities." + id + ".present", true); + for (Ability.AbilityParameter parameter : parameters) + config.set("abilities." + id + ".parameters." + parameter.getParameter().getId(), parameter.getValue()); + }); + } + public void setPropertyValue(ItemProperty property, T value) { propertiesValue.put(property.getId(), value); } @@ -89,6 +129,8 @@ public ItemStack asItem() { if (getPropertyValue(Boolean.class, "enabled")) { ItemStack base = XMaterial.GRASS_BLOCK.parseItem(); for (ItemProperty property : properties) { + if (!property.isSavable()) + continue; final Object obj = propertiesValue.get(property.getId()); if (obj != null && property.isCompatible(this).isEmpty()) { base = property.apply(base, obj).clone(); @@ -107,6 +149,10 @@ public ItemStack asItem() { } } + public HashMap getAbilities() { + return abilities; + } + public List getProperties() { return properties; } @@ -137,4 +183,30 @@ public void toggleEnabled() { public boolean isEnabled() { return getPropertyValue(Boolean.class, "enabled"); } + + public List getFormattedAbilities() { + return abilities.keySet() + .stream() + .map(id -> ItemCreator.getInstance() + .getRegisteredAbilities() + .values() + .stream() + .filter(ab -> ab.getId().equals(id)).findAny().orElse(null)) + .collect(Collectors.toList()); + } + + public boolean hasAbility(Ability ability) { + return abilities.containsKey(ability.getId()); + } + + public Ability.AbilityParameter[] getAbilityParameters(Ability ability) { + return abilities.getOrDefault(ability.getId(), new Ability.AbilityParameter[0]); + } + + public void setAbilityParameter(Ability ability, Ability.AbilityParameter parameter, Object value) { + final List current = new ArrayList<>(List.of(getAbilityParameters(ability))); + current.removeIf(par -> par.getParameter().getId().equals(parameter.getParameter().getId())); + current.add(new Ability.AbilityParameter<>(value, parameter.getParameter())); + abilities.put(ability.getId(), current.toArray(new Ability.AbilityParameter[0])); + } } diff --git a/src/main/java/info/itsthesky/itemcreator/core/ItemCreatorAPIImpl.java b/src/main/java/info/itsthesky/itemcreator/core/ItemCreatorAPIImpl.java index 44bc8fd..234ad9b 100644 --- a/src/main/java/info/itsthesky/itemcreator/core/ItemCreatorAPIImpl.java +++ b/src/main/java/info/itsthesky/itemcreator/core/ItemCreatorAPIImpl.java @@ -4,6 +4,8 @@ import de.tr7zw.changeme.nbtapi.NBTItem; import info.itsthesky.itemcreator.ItemCreator; import info.itsthesky.itemcreator.api.ItemCreatorAPI; +import info.itsthesky.itemcreator.api.abilities.Ability; +import info.itsthesky.itemcreator.api.abilities.RawAbilityParameter; import info.itsthesky.itemcreator.api.properties.base.ItemProperty; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; @@ -11,6 +13,8 @@ import org.jetbrains.annotations.Nullable; import java.io.File; +import java.util.ArrayList; +import java.util.List; public class ItemCreatorAPIImpl implements ItemCreatorAPI { @@ -26,7 +30,22 @@ public ItemCreatorAPIImpl(ItemCreator instance) { final boolean disabled = new File(instance.getDataFolder(), "items/-" + id + ".yml").exists(); final CustomItem item = new CustomItem(id); final Config config = getItemConfig(item); + for (Ability ability : ItemCreator.getInstance().getRegisteredAbilities().values()) { + if (!config.getOrDefault("abilities." + ability.getId() + ".present", false)) + continue; + final List parameters = new ArrayList<>(); + for (String parameterID : config.singleLayerKeySet("abilities." + ability.getId() + ".parameters")) { + final RawAbilityParameter parameter = ItemCreator.getInstance().getParameterFromId(parameterID); + parameters.add(new Ability.AbilityParameter<>( + config.getOrSetDefault("abilities." + ability.getId() + ".parameters." + parameterID, parameter.getDefaultValue()), + parameter)); + } + item.registerAbility(ability, parameters.toArray(new Ability.AbilityParameter[0])); + //item.setAbilityParameters(ability, parameters.toArray(new Ability.AbilityParameter[0])); + } for (ItemProperty property : ItemCreator.getInstance().getRegisteredProperties().values()) { + if (!property.isSavable()) + continue; item.registerProperty(property); if (config.contains(property.getId())) { final Object value; @@ -78,6 +97,20 @@ public void registerProperty(ItemProperty property) { instance.getRegisteredProperties().put(prop, property); } + private int abil = 1; + @Override + public void registerAbility(Ability ability) { + abil++; + instance.getRegisteredAbilities().put(abil, ability); + } + + private int params = 1; + @Override + public void registerParameter(RawAbilityParameter parameter) { + instance.getRegisteredParameters().put(params, parameter); + params++; + } + @Override public @NotNull File getItemFile(CustomItem item) { return new File(instance.getDataFolder(), "items/" + item.getId() + ".yml"); diff --git a/src/main/java/info/itsthesky/itemcreator/core/ParameterImpl.java b/src/main/java/info/itsthesky/itemcreator/core/ParameterImpl.java new file mode 100644 index 0000000..0579371 --- /dev/null +++ b/src/main/java/info/itsthesky/itemcreator/core/ParameterImpl.java @@ -0,0 +1,45 @@ +package info.itsthesky.itemcreator.core; + +import com.cryptomorin.xseries.XMaterial; +import info.itsthesky.itemcreator.api.abilities.RawAbilityParameter; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.BiFunction; + +public class ParameterImpl implements RawAbilityParameter { + + private final String id; + private final XMaterial material; + private final T def; + private final BiFunction parser; + + public ParameterImpl(String id, XMaterial material, T def, + BiFunction parser) { + this.id = id; + this.material = material; + this.def = def; + this.parser = parser; + } + + @Override + public String getId() { + return id; + } + + @Override + public XMaterial getMaterial() { + return material; + } + + @Override + public T getDefaultValue() { + return def; + } + + @Override + public T parse(@NotNull String input, @Nullable Player player) { + return parser.apply(input, player); + } +} diff --git a/src/main/java/info/itsthesky/itemcreator/core/abilities/ItemThrow.java b/src/main/java/info/itsthesky/itemcreator/core/abilities/ItemThrow.java new file mode 100644 index 0000000..e5d7f01 --- /dev/null +++ b/src/main/java/info/itsthesky/itemcreator/core/abilities/ItemThrow.java @@ -0,0 +1,67 @@ +package info.itsthesky.itemcreator.core.abilities; + +import com.cryptomorin.xseries.XMaterial; +import info.itsthesky.itemcreator.api.abilities.DefaultParameters; +import info.itsthesky.itemcreator.api.abilities.RawAbilityParameter; +import info.itsthesky.itemcreator.api.abilities.RightClickAbility; +import info.itsthesky.itemcreator.core.CustomItem; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ItemThrow extends RightClickAbility implements Listener { + + public ItemThrow(JavaPlugin plugin) { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @Override + public String getId() { + return "item_throw"; + } + + @Override + public @NotNull Player getPlayer(PlayerInteractEvent event) { + return event.getPlayer(); + } + + @Override + public XMaterial getMaterial() { + return XMaterial.FISHING_ROD; + } + + @Override + public @NotNull RawAbilityParameter[] getParameters() { + return new RawAbilityParameter[] { + DefaultParameters.ABILITY_COOLDOWN, + DefaultParameters.ABILITY_FORCE + }; + } + + @Override + public void launch(@NotNull PlayerInteractEvent event, @Nullable CustomItem citem, @NotNull AbilityParameter[] parameters) { + if (citem == null) + return; + event.setCancelled(true); + final Number force = ((Number) parameters[1].getValue()).doubleValue() / 10; + final Player player = event.getPlayer(); + final ItemStack tool = player.getInventory().getItemInMainHand().clone(); + tool.setAmount(1); + + final ItemStack editedItem = player.getInventory().getItemInMainHand().clone(); + if (editedItem.getAmount() > 0) + editedItem.setAmount(editedItem.getAmount() - 1); + player.getInventory().setItemInMainHand(editedItem); + + player.getWorld().dropItem(player.getLocation().clone().add(0, 1, 0), tool, item -> { + final Vector direction = player.getLocation().getDirection().normalize(); + item.setVelocity(new Vector(direction.getX(), direction.getY() + force.doubleValue(), direction.getZ())); + }); + } + +} diff --git a/src/main/java/info/itsthesky/itemcreator/core/gui/EditorGUI.java b/src/main/java/info/itsthesky/itemcreator/core/gui/EditorGUI.java index 4fc7018..94b0284 100644 --- a/src/main/java/info/itsthesky/itemcreator/core/gui/EditorGUI.java +++ b/src/main/java/info/itsthesky/itemcreator/core/gui/EditorGUI.java @@ -44,6 +44,10 @@ public EditorGUI(final CustomItem item, final boolean openedFromGUI, final Playe } }); + /* + Pages navigation + */ + setItem(49, SkullCreator.itemWithBase64(new ItemBuilder(XMaterial.PLAYER_HEAD.parseItem()) .name(LangLoader.get().format("gui.items.page_info.name")) .lore(LangLoader.get().formatsList("gui.items.page_info.lore", @@ -53,13 +57,6 @@ public EditorGUI(final CustomItem item, final boolean openedFromGUI, final Playe ItemCreator.getInstance().getRegisteredProperties().size())) .build(), "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTdlZDY2ZjVhNzAyMDlkODIxMTY3ZDE1NmZkYmMwY2EzYmYxMWFkNTRlZDVkODZlNzVjMjY1ZjdlNTAyOWVjMSJ9fX0=")); - final ItemProperty enabledProperty = item.getProperties() - .stream() - .filter(prop -> prop.getId().equals("enabled")) - .findAny() - .orElse(null); - setItem(8, enabledProperty.asMenuItem(), ev -> enabledProperty.onEditorClick(ev, item)); - setItem(45, SkullCreator.itemWithBase64(new ItemBuilder(XMaterial.PLAYER_HEAD.parseItem()) .name(LangLoader.get().format("gui.items.previous")) .build(), "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNWFlNzg0NTFiZjI2Y2Y0OWZkNWY1NGNkOGYyYjM3Y2QyNWM5MmU1Y2E3NjI5OGIzNjM0Y2I1NDFlOWFkODkifX19"), ev -> { @@ -82,6 +79,15 @@ public EditorGUI(final CustomItem item, final boolean openedFromGUI, final Playe } }); + /* End navigation */ + + final ItemProperty enabledProperty = item.getProperties() + .stream() + .filter(prop -> prop.getId().equals("enabled")) + .findAny() + .orElse(null); + setItem(8, enabledProperty.asMenuItem(), ev -> enabledProperty.onEditorClick(ev, item)); + int i = -1; final List slots = Arrays.asList(19, 20, 21, 22, 23, 24, 25, @@ -113,14 +119,15 @@ public EditorGUI(final CustomItem item, final boolean openedFromGUI, final Playe LangLoader.get().format("property.clear_info"))); } else { final MultipleItemProperty mitem = (MultipleItemProperty) property; - for (String line : LangLoader.get().formatsList("property.general_multiple_lore")) { - line = line.replace("%1", mitem.getActionLore()); - if (line.contains("%2")) - for (Object s : mitem.formatGUI(item.getPropertyValue(mitem))) - lores.add(Utils.colored(s.toString())); - else - lores.add(Utils.colored(line)); - } + if (property.isSavable()) + for (String line : LangLoader.get().formatsList("property.general_multiple_lore")) { + line = line.replace("%1", mitem.getActionLore()); + if (line.contains("%2")) + for (Object s : mitem.formatGUI(item.getPropertyValue(mitem))) + lores.add(Utils.colored(s.toString())); + else + lores.add(Utils.colored(line)); + } } if (value instanceof Boolean && ((Boolean) value)) builder.enchant(Enchantment.LOOT_BONUS_BLOCKS); diff --git a/src/main/java/info/itsthesky/itemcreator/core/gui/ItemListGUI.java b/src/main/java/info/itsthesky/itemcreator/core/gui/ItemListGUI.java index 16205c0..4e48526 100644 --- a/src/main/java/info/itsthesky/itemcreator/core/gui/ItemListGUI.java +++ b/src/main/java/info/itsthesky/itemcreator/core/gui/ItemListGUI.java @@ -77,7 +77,6 @@ public ItemListGUI(final List items, Player opener) { items.size())) .build(), "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTdlZDY2ZjVhNzAyMDlkODIxMTY3ZDE1NmZkYmMwY2EzYmYxMWFkNTRlZDVkODZlNzVjMjY1ZjdlNTAyOWVjMSJ9fX0=")); - setItem(53, SkullCreator.itemWithBase64(new ItemBuilder(XMaterial.PLAYER_HEAD.parseItem()) .name(LangLoader.get().format("gui.items.next")) .build(), "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTE3ZjM2NjZkM2NlZGZhZTU3Nzc4Yzc4MjMwZDQ4MGM3MTlmZDVmNjVmZmEyYWQzMjU1Mzg1ZTQzM2I4NmUifX19"), ev -> { diff --git a/src/main/java/info/itsthesky/itemcreator/core/gui/abilities/AbilityListGUI.java b/src/main/java/info/itsthesky/itemcreator/core/gui/abilities/AbilityListGUI.java new file mode 100644 index 0000000..13ad7de --- /dev/null +++ b/src/main/java/info/itsthesky/itemcreator/core/gui/abilities/AbilityListGUI.java @@ -0,0 +1,124 @@ +package info.itsthesky.itemcreator.core.gui.abilities; + +import com.cryptomorin.xseries.XMaterial; +import dev.dbassett.skullcreator.SkullCreator; +import fr.mrmicky.fastinv.FastInv; +import fr.mrmicky.fastinv.ItemBuilder; +import info.itsthesky.itemcreator.ItemCreator; +import info.itsthesky.itemcreator.api.abilities.Ability; +import info.itsthesky.itemcreator.api.properties.base.ItemProperty; +import info.itsthesky.itemcreator.core.CustomItem; +import info.itsthesky.itemcreator.core.gui.EditorGUI; +import info.itsthesky.itemcreator.core.gui.ItemListGUI; +import info.itsthesky.itemcreator.core.langs.LangLoader; +import info.itsthesky.itemcreator.utils.ChatWaiter; +import info.itsthesky.itemcreator.utils.Pagination; +import info.itsthesky.itemcreator.utils.Utils; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + +public class AbilityListGUI extends FastInv { + + private static final HashMap playersPages = new HashMap<>(); + private static int getPlayerPage(Player player) { + return playersPages.getOrDefault(player.getUniqueId(), 0); + } + + public AbilityListGUI(final CustomItem item, final Player player) { + super(6 * 9, LangLoader.get().format("gui.title.abilities_list")); + final Pagination abilities = new Pagination<>(22, item.getFormattedAbilities()); + setItems(getBorders(), new ItemBuilder(XMaterial.GREEN_STAINED_GLASS_PANE.parseItem()) + .name(Utils.colored("&1")) + .build()); + + setItem(0, new ItemBuilder(XMaterial.ARROW.parseMaterial()) + .name(LangLoader.get().format("gui.items.back")).build(), ev -> { + new EditorGUI(item, true, player).open(player); + }); + + /* + Pages navigation + */ + + if (abilities.exists(0)) { + setItem(49, SkullCreator.itemWithBase64(new ItemBuilder(XMaterial.PLAYER_HEAD.parseItem()) + .name(LangLoader.get().format("gui.items.page_info.name")) + .lore(LangLoader.get().formatsList("gui.items.page_info.lore", + getPlayerPage(player) + 1, + abilities.totalPages(), + abilities.getPage(getPlayerPage(player)).size(), + ItemCreator.getInstance().getRegisteredProperties().size())) + .build(), "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTdlZDY2ZjVhNzAyMDlkODIxMTY3ZDE1NmZkYmMwY2EzYmYxMWFkNTRlZDVkODZlNzVjMjY1ZjdlNTAyOWVjMSJ9fX0=")); + + setItem(45, SkullCreator.itemWithBase64(new ItemBuilder(XMaterial.PLAYER_HEAD.parseItem()) + .name(LangLoader.get().format("gui.items.previous")) + .build(), "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNWFlNzg0NTFiZjI2Y2Y0OWZkNWY1NGNkOGYyYjM3Y2QyNWM5MmU1Y2E3NjI5OGIzNjM0Y2I1NDFlOWFkODkifX19"), ev -> { + if (getPlayerPage(player) <= 0) + player.sendMessage(LangLoader.get().format("messages.first_page")); + else { + playersPages.put(player.getUniqueId(), getPlayerPage(player) - 1); + new AbilityListGUI(item, player).open(player); + } + }); + + setItem(53, SkullCreator.itemWithBase64(new ItemBuilder(XMaterial.PLAYER_HEAD.parseItem()) + .name(LangLoader.get().format("gui.items.next")) + .build(), "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTE3ZjM2NjZkM2NlZGZhZTU3Nzc4Yzc4MjMwZDQ4MGM3MTlmZDVmNjVmZmEyYWQzMjU1Mzg1ZTQzM2I4NmUifX19"), ev -> { + if (getPlayerPage(player) + 1 >= abilities.totalPages()) + player.sendMessage(LangLoader.get().format("messages.last_page")); + else { + playersPages.put(player.getUniqueId(), getPlayerPage(player) + 1); + new AbilityListGUI(item, player).open(player); + } + }); + + int i = -1; + final List slots = + Arrays.asList(19, 20, 21, 22, 23, 24, 25, + 28, 29, 30, 31, 32, 33, 34, + 37, 38, 39, 40, 41, 42, 43); + for (Ability ability : abilities.getPage(getPlayerPage(player))) { + i++; + setItem(slots.get(i), ability.getRepresentation().asItem(), ev -> { + new ParametersListGUI(ability, item, player).open(player); + }); + } + + } else { + setItem(31, new ItemBuilder(XMaterial.BARRIER.parseItem()) + .name(LangLoader.get().format("gui.items.no_abilities.name")) + .lore(LangLoader.get().formatsList("gui.items.no_abilities.lore")) + .build()); + } + + setItem(8, new ItemBuilder(XMaterial.SLIME_BALL.parseItem()) + .name(LangLoader.get().format("gui.items.add_ability.name")) + .lore(LangLoader.get().formatsList("gui.items.add_ability.lore")) + .build(), ev -> { + player.closeInventory(); + player.sendMessage(LangLoader.get().format("messages.enter_ability_id")); + new ChatWaiter(player, e -> { + final String id = e.getMessage(); + final @Nullable Ability ability = ItemCreator.getInstance().getAbilityFromId(id); + if (ability == null) { + player.sendMessage(LangLoader.get().format("messages.wrong_ability_id")); + } else if (item.hasAbility(ability)) { + player.sendMessage(LangLoader.get().format("messages.ability_already_added")); + } else { + player.sendMessage(LangLoader.get().format("messages.ability_added")); + item.registerAbility(ability); + new AbilityListGUI(item, player).open(player); + return; + } + open(player); + }, true, true); + }); + + /* End navigation */ + } +} diff --git a/src/main/java/info/itsthesky/itemcreator/core/gui/abilities/ParametersListGUI.java b/src/main/java/info/itsthesky/itemcreator/core/gui/abilities/ParametersListGUI.java new file mode 100644 index 0000000..c9bb412 --- /dev/null +++ b/src/main/java/info/itsthesky/itemcreator/core/gui/abilities/ParametersListGUI.java @@ -0,0 +1,94 @@ +package info.itsthesky.itemcreator.core.gui.abilities; + +import com.cryptomorin.xseries.XMaterial; +import dev.dbassett.skullcreator.SkullCreator; +import fr.mrmicky.fastinv.FastInv; +import fr.mrmicky.fastinv.ItemBuilder; +import info.itsthesky.itemcreator.ItemCreator; +import info.itsthesky.itemcreator.api.abilities.Ability; +import info.itsthesky.itemcreator.core.CustomItem; +import info.itsthesky.itemcreator.core.langs.LangLoader; +import info.itsthesky.itemcreator.utils.ChatWaiter; +import info.itsthesky.itemcreator.utils.Pagination; +import info.itsthesky.itemcreator.utils.Utils; +import org.bukkit.entity.Player; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + +public class ParametersListGUI extends FastInv { + + private static final HashMap playersPages = new HashMap<>(); + private static int getPlayerPage(Player player) { + return playersPages.getOrDefault(player.getUniqueId(), 0); + } + + public ParametersListGUI(final Ability ability, final CustomItem item, final Player player) { + super(9 * 6, LangLoader.get().format("gui.title.parameters")); + final Pagination parameters = new Pagination<>(22, item.getAbilityParameters(ability)); + setItems(getBorders(), new ItemBuilder(XMaterial.GREEN_STAINED_GLASS_PANE.parseItem()) + .name(Utils.colored("&1")) + .build()); + + setItem(0, new ItemBuilder(XMaterial.ARROW.parseMaterial()) + .name(LangLoader.get().format("gui.items.back")).build(), ev -> { + new AbilityListGUI(item, player).open(player); + }); + + setItem(49, SkullCreator.itemWithBase64(new ItemBuilder(XMaterial.PLAYER_HEAD.parseItem()) + .name(LangLoader.get().format("gui.items.page_info.name")) + .lore(LangLoader.get().formatsList("gui.items.page_info.lore", + getPlayerPage(player) + 1, + parameters.totalPages(), + parameters.getPage(getPlayerPage(player)).size(), + ItemCreator.getInstance().getRegisteredProperties().size())) + .build(), "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTdlZDY2ZjVhNzAyMDlkODIxMTY3ZDE1NmZkYmMwY2EzYmYxMWFkNTRlZDVkODZlNzVjMjY1ZjdlNTAyOWVjMSJ9fX0=")); + + setItem(45, SkullCreator.itemWithBase64(new ItemBuilder(XMaterial.PLAYER_HEAD.parseItem()) + .name(LangLoader.get().format("gui.items.previous")) + .build(), "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNWFlNzg0NTFiZjI2Y2Y0OWZkNWY1NGNkOGYyYjM3Y2QyNWM5MmU1Y2E3NjI5OGIzNjM0Y2I1NDFlOWFkODkifX19"), ev -> { + if (getPlayerPage(player) <= 0) + player.sendMessage(LangLoader.get().format("messages.first_page")); + else { + playersPages.put(player.getUniqueId(), getPlayerPage(player) - 1); + new ParametersListGUI(ability, item, player).open(player); + } + }); + + setItem(53, SkullCreator.itemWithBase64(new ItemBuilder(XMaterial.PLAYER_HEAD.parseItem()) + .name(LangLoader.get().format("gui.items.next")) + .build(), "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTE3ZjM2NjZkM2NlZGZhZTU3Nzc4Yzc4MjMwZDQ4MGM3MTlmZDVmNjVmZmEyYWQzMjU1Mzg1ZTQzM2I4NmUifX19"), ev -> { + if (getPlayerPage(player) + 1 >= parameters.totalPages()) + player.sendMessage(LangLoader.get().format("messages.last_page")); + else { + playersPages.put(player.getUniqueId(), getPlayerPage(player) + 1); + new ParametersListGUI(ability, item, player).open(player); + } + }); + + int i = -1; + final List slots = + Arrays.asList(19, 20, 21, 22, 23, 24, 25, + 28, 29, 30, 31, 32, 33, 34, + 37, 38, 39, 40, 41, 42, 43); + for (Ability.AbilityParameter parameter : parameters.getPage(getPlayerPage(player))) { + i++; + setItem(slots.get(i), parameter.getParameter().getRepresentation().asItem(), ev -> { + player.closeInventory(); + player.sendMessage(LangLoader.get().format("messages.enter_parameter_value")); + new ChatWaiter(player, event -> { + final String rawValue = event.getMessage(); + final Object value = parameter.getParameter().parse(rawValue, player); + if (value != null) { + item.setAbilityParameter(ability, parameter, value); + item.saveAbilities(); + player.sendMessage(LangLoader.get().format("messages.parameter_changed")); + } + new ParametersListGUI(ability, item, player).open(player); + }, true, true); + }); + } + } +} diff --git a/src/main/java/info/itsthesky/itemcreator/core/properties/AbilitiesProperty.java b/src/main/java/info/itsthesky/itemcreator/core/properties/AbilitiesProperty.java new file mode 100644 index 0000000..77c7105 --- /dev/null +++ b/src/main/java/info/itsthesky/itemcreator/core/properties/AbilitiesProperty.java @@ -0,0 +1,38 @@ +package info.itsthesky.itemcreator.core.properties; + +import com.cryptomorin.xseries.XMaterial; +import info.itsthesky.itemcreator.api.properties.base.MenuProperty; +import info.itsthesky.itemcreator.core.CustomItem; +import info.itsthesky.itemcreator.core.gui.abilities.AbilityListGUI; +import info.itsthesky.itemcreator.core.langs.LangLoader; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class AbilitiesProperty extends MenuProperty { + + @Override + public XMaterial getMaterial() { + return XMaterial.FIRE_CHARGE; + } + + @Override + public List isCompatible(CustomItem item) { + if (!item.hasPropertySet("ic_tag")) + return Collections.singletonList(LangLoader.get().format("property.property_require", + LangLoader.get().format("property.ic_tag.name"))); + return new ArrayList<>(); + } + + @Override + public void onClick(Player player, CustomItem item) { + new AbilityListGUI(item, player).open(player); + } + + @Override + public String getId() { + return "abilities"; + } +} diff --git a/src/main/java/info/itsthesky/itemcreator/core/properties/events/CommandsProperty.java b/src/main/java/info/itsthesky/itemcreator/core/properties/events/CommandsProperty.java index 9c70d19..a3800a0 100644 --- a/src/main/java/info/itsthesky/itemcreator/core/properties/events/CommandsProperty.java +++ b/src/main/java/info/itsthesky/itemcreator/core/properties/events/CommandsProperty.java @@ -96,13 +96,17 @@ public void onItemClick(PlayerInteractEvent e) { final NBTItem nbtItem = new NBTItem(e.getItem()); if (!nbtItem.hasKey(getId())) return; - final List commands = Stream - .of(nbtItem.getString(getId()).split("\\|")) - .map(CommandData::serialize) - .collect(Collectors.toList()); - for (CommandData cmd : commands) - if (cmd.getAction().equals(e.getAction())) - player.performCommand(cmd.getCommand()); + try { + final List commands = Stream + .of(nbtItem.getString(getId()).split("\\|")) + .map(CommandData::serialize) + .collect(Collectors.toList()); + for (CommandData cmd : commands) + if (cmd.getAction().equals(e.getAction())) + player.performCommand(cmd.getCommand()); + } catch (Exception ignored) { + + } } @Override diff --git a/src/main/java/info/itsthesky/itemcreator/utils/Utils.java b/src/main/java/info/itsthesky/itemcreator/utils/Utils.java index 9624620..96b3da3 100644 --- a/src/main/java/info/itsthesky/itemcreator/utils/Utils.java +++ b/src/main/java/info/itsthesky/itemcreator/utils/Utils.java @@ -21,6 +21,10 @@ public static T verify(Supplier supplier) { } public static String beauty(Enum enumeration) { - return WordUtils.capitalize(enumeration.name().replace("_", " ").toLowerCase()); + return beauty(enumeration.name()); + } + + public static String beauty(String input) { + return WordUtils.capitalize(input.replace("_", " ").toLowerCase()); } }