mirror of
https://github.com/HibiscusMC/HMCCosmetics.git
synced 2026-01-04 15:41:45 +00:00
Improved GUI
This commit is contained in:
@@ -1,13 +1,18 @@
|
||||
package io.github.fisher2911.hmccosmetics.config;
|
||||
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import dev.triumphteam.gui.components.GuiAction;
|
||||
import dev.triumphteam.gui.guis.GuiItem;
|
||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
||||
import io.github.fisher2911.hmccosmetics.gui.CosmeticGui;
|
||||
import io.github.fisher2911.hmccosmetics.message.Message;
|
||||
import io.github.fisher2911.hmccosmetics.message.MessageHandler;
|
||||
import io.github.fisher2911.hmccosmetics.message.Placeholder;
|
||||
import io.github.fisher2911.hmccosmetics.user.User;
|
||||
import io.github.fisher2911.hmccosmetics.util.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
@@ -16,17 +21,28 @@ import org.spongepowered.configurate.serialize.TypeSerializer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ActionSerializer implements TypeSerializer<GuiAction<InventoryClickEvent>> {
|
||||
public class ActionSerializer implements TypeSerializer<List<CosmeticGuiAction>> {
|
||||
|
||||
public static final ActionSerializer INSTANCE = new ActionSerializer();
|
||||
private static final HMCCosmetics plugin;
|
||||
|
||||
private static final String OPEN_MENU = "open-menu";
|
||||
private static final String SET_ITEMS = "set-items";
|
||||
private static final String ON_EQUIP = "equip";
|
||||
private static final String ON_REMOVE = "unequip";
|
||||
private static final String ANY = "any";
|
||||
private static final String SEND_MESSAGE = "send-message";
|
||||
private static final String SEND_MESSAGES = "send-messages";
|
||||
private static final String SEND_COMMAND = "send-command";
|
||||
private static final String SEND_COMMANDS = "send-commands";
|
||||
private static final String SOUND = "sound";
|
||||
private static final String SOUND_NAME = "name";
|
||||
private static final String SOUND_VOLUME = "volume";
|
||||
@@ -51,33 +67,43 @@ public class ActionSerializer implements TypeSerializer<GuiAction<InventoryClick
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuiAction<InventoryClickEvent> deserialize(final Type type, final ConfigurationNode source) {
|
||||
final var children = source.childrenMap();
|
||||
final List<Consumer<InventoryClickEvent>> consumers = new ArrayList<>();
|
||||
for (final var entry : children.entrySet()) {
|
||||
final String clickType = entry.getKey().toString();
|
||||
if (clickType == null) continue;
|
||||
consumers.add(this.parseAction(entry.getValue(), clickType.toUpperCase(Locale.ROOT)));
|
||||
}
|
||||
|
||||
return event -> {
|
||||
for (final Consumer<InventoryClickEvent> consumer : consumers) {
|
||||
consumer.accept(event);
|
||||
}
|
||||
};
|
||||
public List<CosmeticGuiAction> deserialize(final Type type, final ConfigurationNode source) {
|
||||
return this.deserialize(type, new ArrayList<>(), source, CosmeticGuiAction.When.ALL);
|
||||
}
|
||||
|
||||
private Consumer<InventoryClickEvent> parseAction(final ConfigurationNode node, final String clickType) {
|
||||
private List<CosmeticGuiAction> deserialize(
|
||||
final Type type,
|
||||
final List<CosmeticGuiAction> consumers,
|
||||
final ConfigurationNode source,
|
||||
final CosmeticGuiAction.When when) {
|
||||
final var children = source.childrenMap();
|
||||
for (final var entry : children.entrySet()) {
|
||||
final String clickType = entry.getKey().toString();
|
||||
try {
|
||||
final CosmeticGuiAction.When nextWhen = CosmeticGuiAction.When.valueOf(clickType.toUpperCase());
|
||||
this.deserialize(type, consumers, entry.getValue(), nextWhen);
|
||||
} catch (final IllegalArgumentException exception) {
|
||||
consumers.add(this.parseAction(entry.getValue(), clickType.toUpperCase(Locale.ROOT), when));
|
||||
}
|
||||
}
|
||||
|
||||
return consumers;
|
||||
}
|
||||
|
||||
private CosmeticGuiAction parseAction(
|
||||
final ConfigurationNode node,
|
||||
final String clickType,
|
||||
final CosmeticGuiAction.When when
|
||||
) {
|
||||
final ConfigurationNode openMenuNode = node.node(OPEN_MENU);
|
||||
final ConfigurationNode sendMessageNode = node.node(SEND_MESSAGE);
|
||||
final ConfigurationNode soundNode = node.node(SOUND);
|
||||
final ConfigurationNode soundNameNode = soundNode.node(SOUND_NAME);
|
||||
final ConfigurationNode volumeNode = soundNode.node(SOUND_VOLUME);
|
||||
final ConfigurationNode pitchNode = soundNode.node(SOUND_PITCH);
|
||||
final ConfigurationNode categoryNode = soundNode.node(SOUND_CATEGORY);
|
||||
final ConfigurationNode setItemsNode = node.node(SET_ITEMS);
|
||||
|
||||
final String openMenu = openMenuNode.getString();
|
||||
final String sendMessage = sendMessageNode.getString();
|
||||
|
||||
final SoundData soundData;
|
||||
|
||||
@@ -97,24 +123,127 @@ public class ActionSerializer implements TypeSerializer<GuiAction<InventoryClick
|
||||
}
|
||||
|
||||
final ClickType click = Utils.stringToEnum(clickType, ClickType.class, ClickType.UNKNOWN);
|
||||
final Map<Integer, GuiItem> setItems = this.loadSetItems(setItemsNode);
|
||||
|
||||
return event -> {
|
||||
if (click != ClickType.UNKNOWN && event.getClick() != click) return;
|
||||
if (!(event.getWhoClicked() instanceof final Player player)) return;
|
||||
if (soundData != null) {
|
||||
soundData.play(player);
|
||||
final Consumer<Player> messageConsumer = this.loadMessages(node, plugin);
|
||||
|
||||
return new CosmeticGuiAction(
|
||||
when,
|
||||
event -> {
|
||||
if (click != ClickType.UNKNOWN && event.getClick() != click) return;
|
||||
if (!(event.getWhoClicked() instanceof final Player player)) return;
|
||||
if (soundData != null) {
|
||||
soundData.play(player);
|
||||
}
|
||||
|
||||
if (openMenu != null) plugin.getCosmeticsMenu().openMenu(openMenu, event.getWhoClicked());
|
||||
messageConsumer.accept(player);
|
||||
final Optional<User> optionalUser = plugin.getUserManager().get(player.getUniqueId());
|
||||
if (optionalUser.isEmpty()) return;
|
||||
final User user = optionalUser.get();
|
||||
final CosmeticGui gui = user.getOpenGui();
|
||||
if (gui != null) {
|
||||
for (final var entry : setItems.entrySet()) {
|
||||
final GuiItem item = entry.getValue();
|
||||
gui.updateItem(entry.getKey(), item, user, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private Map<Integer, GuiItem> loadSetItems(final ConfigurationNode node) {
|
||||
if (node.virtual()) return Collections.emptyMap();
|
||||
final Map<Integer, GuiItem> setItems = new HashMap<>();
|
||||
try {
|
||||
for (final var entry : node.childrenMap().entrySet()) {
|
||||
if (!(entry.getKey() instanceof final Integer slot)) continue;
|
||||
final var key = entry.getValue();
|
||||
final GuiItem guiItem = ItemSerializer.INSTANCE.deserialize(GuiItem.class, key);
|
||||
if (guiItem == null) continue;
|
||||
setItems.put(slot, guiItem);
|
||||
}
|
||||
} catch (final SerializationException exception) {
|
||||
HMCCosmetics.getPlugin(HMCCosmetics.class).getLogger().severe(
|
||||
"Error loading set-items"
|
||||
);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
return setItems;
|
||||
}
|
||||
|
||||
private static final String CONSOLE = "console";
|
||||
private static final String PLAYER = "player";
|
||||
|
||||
private Consumer<Player> loadMessages(final ConfigurationNode source, final HMCCosmetics plugin) {
|
||||
final ConfigurationNode messageNode = source.node(SEND_MESSAGE);
|
||||
final ConfigurationNode messagesNode = source.node(SEND_MESSAGES);
|
||||
final ConfigurationNode commandNode = source.node(SEND_COMMAND);
|
||||
final ConfigurationNode commandsNode = source.node(SEND_COMMANDS);
|
||||
|
||||
final List<String> messages = new ArrayList<>();
|
||||
final List<String> commands = new ArrayList<>();
|
||||
|
||||
final String message = messageNode.getString();
|
||||
if (message != null) messages.add(message);
|
||||
final String command = commandNode.getString();
|
||||
if (command != null) commands.add(command);
|
||||
|
||||
for (final var node : messagesNode.childrenList()) {
|
||||
final String listMessage = node.getString();
|
||||
if (listMessage == null) continue;
|
||||
messages.add(listMessage);
|
||||
}
|
||||
|
||||
for (final var node : commandsNode.childrenList()) {
|
||||
final String commandMessage = node.getString();
|
||||
if (commandMessage == null) continue;
|
||||
commands.add(commandMessage);
|
||||
}
|
||||
|
||||
return player -> {
|
||||
final String playerName = player.getName();
|
||||
final Map<String, String> placeholders = Map.of(Placeholder.PLAYER, playerName);
|
||||
final MessageHandler messageHandler = plugin.getMessageHandler();
|
||||
for (final String sendMessage : messages) {
|
||||
messageHandler.sendMessage(
|
||||
player,
|
||||
new Message("", sendMessage),
|
||||
placeholders
|
||||
);
|
||||
}
|
||||
|
||||
if (sendMessage != null) plugin.getMessageHandler().sendMessage(
|
||||
player,
|
||||
new Message("", sendMessage)
|
||||
);
|
||||
if (openMenu != null) plugin.getCosmeticsMenu().openMenu(openMenu, event.getWhoClicked());
|
||||
for (final String sendCommand : commands) {
|
||||
final String[] parts = sendCommand.split(":");
|
||||
if (parts.length < 2) {
|
||||
Bukkit.dispatchCommand(
|
||||
Bukkit.getConsoleSender(),
|
||||
sendCommand.replace(Placeholder.PLAYER, playerName)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
final String sender = parts[0];
|
||||
final String commandToSend = parts[1];
|
||||
|
||||
if (sender.equalsIgnoreCase(CONSOLE)) {
|
||||
Bukkit.dispatchCommand(
|
||||
Bukkit.getConsoleSender(),
|
||||
commandToSend.replace(Placeholder.PLAYER, playerName)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
player.chat("/" + commandToSend.replace(Placeholder.PLAYER, playerName));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(final Type type, @Nullable final GuiAction<InventoryClickEvent> obj, final ConfigurationNode node) throws SerializationException {
|
||||
public void serialize(final Type type, @Nullable final List<CosmeticGuiAction> obj, final ConfigurationNode node) throws SerializationException {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.github.fisher2911.hmccosmetics.config;
|
||||
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class CosmeticGuiAction {
|
||||
|
||||
private final When when;
|
||||
private final Consumer<InventoryClickEvent> consumer;
|
||||
|
||||
public CosmeticGuiAction(final When when, final Consumer<InventoryClickEvent> consumer) {
|
||||
this.when = when;
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
public void execute(final InventoryClickEvent event, final When when) {
|
||||
if (this.when != When.ALL && this.when != when) return;
|
||||
consumer.accept(event);
|
||||
}
|
||||
|
||||
public enum When {
|
||||
|
||||
EQUIP,
|
||||
REMOVE,
|
||||
ALL
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,6 @@ import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
@@ -214,7 +213,7 @@ public class ItemSerializer implements TypeSerializer<GuiItem> {
|
||||
itemFlags(itemFlags).
|
||||
build();
|
||||
|
||||
final GuiAction<InventoryClickEvent> action = ActionSerializer.INSTANCE.deserialize(GuiAction.class, actionNode);
|
||||
final List<CosmeticGuiAction> actions = ActionSerializer.INSTANCE.deserialize(GuiAction.class, actionNode);
|
||||
|
||||
Keys.setKey(itemStack);
|
||||
|
||||
@@ -229,7 +228,7 @@ public class ItemSerializer implements TypeSerializer<GuiItem> {
|
||||
|
||||
return new ArmorItem(
|
||||
itemStack,
|
||||
action,
|
||||
actions,
|
||||
Utils.replaceIfNull(idNode.getString(), ""),
|
||||
lockedLore,
|
||||
permission,
|
||||
@@ -240,7 +239,11 @@ public class ItemSerializer implements TypeSerializer<GuiItem> {
|
||||
|
||||
} catch (final IllegalArgumentException exception) {
|
||||
final GuiItem guiItem = dev.triumphteam.gui.builder.item.ItemBuilder.from(itemStack).asGuiItem();
|
||||
guiItem.setAction(action);
|
||||
guiItem.setAction(event -> {
|
||||
for (final CosmeticGuiAction action : actions) {
|
||||
action.execute(event, CosmeticGuiAction.When.ALL);
|
||||
}
|
||||
});
|
||||
return guiItem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,14 @@ package io.github.fisher2911.hmccosmetics.gui;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import dev.triumphteam.gui.components.GuiAction;
|
||||
import dev.triumphteam.gui.guis.GuiItem;
|
||||
import io.github.fisher2911.hmccosmetics.config.CosmeticGuiAction;
|
||||
import io.github.fisher2911.hmccosmetics.util.builder.ColorBuilder;
|
||||
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
@@ -23,23 +26,23 @@ public class ArmorItem extends GuiItem {
|
||||
private final List<String> lockedLore;
|
||||
private final String permission;
|
||||
private final Type type;
|
||||
private GuiAction<InventoryClickEvent> action;
|
||||
private List<CosmeticGuiAction> actions;
|
||||
private boolean dyeable;
|
||||
private int dye;
|
||||
|
||||
public ArmorItem(
|
||||
@NotNull final ItemStack itemStack,
|
||||
final GuiAction<InventoryClickEvent> action,
|
||||
final List<CosmeticGuiAction> actions,
|
||||
final String id,
|
||||
final List<String> lockedLore,
|
||||
final String permission,
|
||||
final Type type,
|
||||
final int dye) {
|
||||
super(itemStack, action);
|
||||
super(itemStack, null);
|
||||
|
||||
this.id = id;
|
||||
this.lockedLore = lockedLore;
|
||||
this.action = action;
|
||||
this.actions = actions;
|
||||
this.permission = permission;
|
||||
this.type = type;
|
||||
this.dye = dye;
|
||||
@@ -55,7 +58,7 @@ public class ArmorItem extends GuiItem {
|
||||
super(itemStack);
|
||||
this.id = id;
|
||||
this.lockedLore = lockedLore;
|
||||
this.action = null;
|
||||
this.actions = new ArrayList<>();
|
||||
this.permission = permission;
|
||||
this.type = type;
|
||||
this.dye = dye;
|
||||
@@ -71,7 +74,7 @@ public class ArmorItem extends GuiItem {
|
||||
super(material);
|
||||
this.id = id;
|
||||
this.lockedLore = lockedLore;
|
||||
this.action = null;
|
||||
this.actions = new ArrayList<>();
|
||||
this.permission = permission;
|
||||
this.type = type;
|
||||
this.dye = dye;
|
||||
@@ -79,16 +82,16 @@ public class ArmorItem extends GuiItem {
|
||||
|
||||
public ArmorItem(
|
||||
@NotNull final Material material,
|
||||
@Nullable final GuiAction<InventoryClickEvent> action,
|
||||
final List<CosmeticGuiAction> actions,
|
||||
final String id,
|
||||
final List<String> lockedLore,
|
||||
final String permission,
|
||||
final Type type,
|
||||
final int dye) {
|
||||
super(material, action);
|
||||
super(material, null);
|
||||
this.id = id;
|
||||
this.lockedLore = lockedLore;
|
||||
this.action = action;
|
||||
this.actions = new ArrayList<>();
|
||||
this.permission = permission;
|
||||
this.type = type;
|
||||
this.dye = dye;
|
||||
@@ -96,17 +99,17 @@ public class ArmorItem extends GuiItem {
|
||||
|
||||
public ArmorItem(
|
||||
@NotNull final ItemStack itemStack,
|
||||
final GuiAction<InventoryClickEvent> action,
|
||||
final List<CosmeticGuiAction> actions,
|
||||
final String id,
|
||||
final List<String> lockedLore,
|
||||
final String permission,
|
||||
final Type type,
|
||||
final boolean dyeable,
|
||||
final int dye) {
|
||||
super(itemStack, action);
|
||||
super(itemStack, null);
|
||||
this.id = id;
|
||||
this.lockedLore = lockedLore;
|
||||
this.action = action;
|
||||
this.actions = actions;
|
||||
this.permission = permission;
|
||||
this.type = type;
|
||||
this.dyeable = dyeable;
|
||||
@@ -124,7 +127,7 @@ public class ArmorItem extends GuiItem {
|
||||
super(itemStack);
|
||||
this.id = id;
|
||||
this.lockedLore = lockedLore;
|
||||
this.action = null;
|
||||
this.actions = new ArrayList<>();
|
||||
this.permission = permission;
|
||||
this.type = type;
|
||||
this.dyeable = dyeable;
|
||||
@@ -142,7 +145,7 @@ public class ArmorItem extends GuiItem {
|
||||
super(material);
|
||||
this.id = id;
|
||||
this.lockedLore = lockedLore;
|
||||
this.action = null;
|
||||
this.actions = new ArrayList<>();
|
||||
this.permission = permission;
|
||||
this.type = type;
|
||||
this.dyeable = dyeable;
|
||||
@@ -161,7 +164,7 @@ public class ArmorItem extends GuiItem {
|
||||
super(material, action);
|
||||
this.id = id;
|
||||
this.lockedLore = lockedLore;
|
||||
this.action = action;
|
||||
this.actions = new ArrayList<>();
|
||||
this.permission = permission;
|
||||
this.type = type;
|
||||
this.dyeable = dyeable;
|
||||
@@ -169,11 +172,11 @@ public class ArmorItem extends GuiItem {
|
||||
}
|
||||
|
||||
public ArmorItem(final ArmorItem armorItem) {
|
||||
super(armorItem.getItemStack(), armorItem.getAction());
|
||||
super(armorItem.getItemStack(), null);
|
||||
this.id = armorItem.getId();
|
||||
this.lockedLore = new ArrayList<>();
|
||||
Collections.copy(armorItem.getLockedLore(), this.lockedLore);
|
||||
this.action = armorItem.getAction();
|
||||
this.actions = armorItem.getActions();
|
||||
this.permission = armorItem.getPermission();
|
||||
this.type = armorItem.getType();
|
||||
this.dyeable = armorItem.isDyeable();
|
||||
@@ -199,14 +202,13 @@ public class ArmorItem extends GuiItem {
|
||||
return lockedLore;
|
||||
}
|
||||
|
||||
public GuiAction<InventoryClickEvent> getAction() {
|
||||
return this.action;
|
||||
public List<CosmeticGuiAction> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAction(final GuiAction<InventoryClickEvent> action) {
|
||||
super.setAction(action);
|
||||
this.action = action;
|
||||
public void setActions(final List<CosmeticGuiAction> actions) {
|
||||
this.actions.clear();
|
||||
this.actions.addAll(actions);
|
||||
}
|
||||
|
||||
public String getPermission() {
|
||||
|
||||
@@ -4,6 +4,7 @@ import dev.triumphteam.gui.components.GuiAction;
|
||||
import dev.triumphteam.gui.guis.Gui;
|
||||
import dev.triumphteam.gui.guis.GuiItem;
|
||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import io.github.fisher2911.hmccosmetics.config.CosmeticGuiAction;
|
||||
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
|
||||
import io.github.fisher2911.hmccosmetics.message.Adventure;
|
||||
import io.github.fisher2911.hmccosmetics.message.MessageHandler;
|
||||
@@ -11,10 +12,13 @@ import io.github.fisher2911.hmccosmetics.message.Messages;
|
||||
import io.github.fisher2911.hmccosmetics.message.Placeholder;
|
||||
import io.github.fisher2911.hmccosmetics.user.User;
|
||||
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
@@ -45,6 +49,7 @@ public class CosmeticGui {
|
||||
this.guiItemMap = guiItemMap;
|
||||
this.itemStackMap = new HashMap<>();
|
||||
this.guiItemMap.forEach((key, value) -> itemStackMap.put(key, value.getItemStack()));
|
||||
|
||||
}
|
||||
|
||||
private void setItems(final User user) {
|
||||
@@ -71,7 +76,7 @@ public class CosmeticGui {
|
||||
final User user,
|
||||
final ArmorItem armorItem,
|
||||
final InventoryClickEvent event,
|
||||
final GuiAction<InventoryClickEvent> actionIfSet) {
|
||||
final List<CosmeticGuiAction> actions) {
|
||||
|
||||
final long current = System.currentTimeMillis();
|
||||
if ((current - this.lastClicked) / 1000. < COOL_DOWN) {
|
||||
@@ -93,7 +98,9 @@ public class CosmeticGui {
|
||||
);
|
||||
|
||||
if (!setTo.isEmpty()) {
|
||||
actionIfSet.execute(event);
|
||||
executeActions(event, actions, CosmeticGuiAction.When.EQUIP);
|
||||
} else {
|
||||
executeActions(event, actions, CosmeticGuiAction.When.REMOVE);
|
||||
}
|
||||
|
||||
final int slot = event.getSlot();
|
||||
@@ -107,6 +114,16 @@ public class CosmeticGui {
|
||||
this.gui.updateItem(slot, guiItem);
|
||||
}
|
||||
|
||||
private void executeActions(
|
||||
final InventoryClickEvent event,
|
||||
final List<CosmeticGuiAction> actions,
|
||||
final CosmeticGuiAction.When when
|
||||
) {
|
||||
for (final CosmeticGuiAction action : actions) {
|
||||
action.execute(event, when);
|
||||
}
|
||||
}
|
||||
|
||||
public void open(final User user, final Player player) {
|
||||
this.gui = Gui.gui().
|
||||
title(Adventure.MINI_MESSAGE.deserialize(
|
||||
@@ -115,6 +132,7 @@ public class CosmeticGui {
|
||||
create();
|
||||
|
||||
this.gui.setDefaultClickAction(event -> event.setCancelled(true));
|
||||
this.gui.setCloseGuiAction(event -> user.setOpenGui(null));
|
||||
|
||||
this.setItems(user);
|
||||
|
||||
@@ -124,17 +142,16 @@ public class CosmeticGui {
|
||||
@Nullable
|
||||
private GuiItem getGuiItem(final User user, final Player player, final int slot) {
|
||||
final GuiItem guiItem = this.guiItemMap.get(slot);
|
||||
|
||||
if (guiItem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final ItemStack itemStack = this.itemStackMap.get(slot);
|
||||
if (itemStack == null) return null;
|
||||
return this.getGuiItem(user, player, guiItem, itemStack);
|
||||
}
|
||||
|
||||
if (itemStack == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private GuiItem getGuiItem(final User user, final Player player, final GuiItem guiItem, final ItemStack itemStack) {
|
||||
if (guiItem instanceof final ArmorItem armorItem) {
|
||||
final String permission =
|
||||
armorItem.getPermission() == null ? "" : armorItem.getPermission();
|
||||
@@ -159,7 +176,7 @@ public class CosmeticGui {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setUserArmor(player, user, cosmeticItem, event, armorItem.getAction());
|
||||
this.setUserArmor(player, user, cosmeticItem, event, armorItem.getActions());
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -172,7 +189,7 @@ public class CosmeticGui {
|
||||
}
|
||||
|
||||
protected ItemStack applyPlaceholders(final User user, final Player player,
|
||||
final ArmorItem armorItem, final boolean hasPermission) {
|
||||
final ArmorItem armorItem, final boolean hasPermission) {
|
||||
final Map<String, String> placeholders = new HashMap<>();
|
||||
|
||||
final PlayerArmor playerArmor = user.getPlayerArmor();
|
||||
@@ -207,6 +224,15 @@ public class CosmeticGui {
|
||||
build();
|
||||
}
|
||||
|
||||
public void updateItem(final int slot, final GuiItem guiItem, final User user, final Player player) {
|
||||
final ItemStack itemStack = guiItem.getItemStack().clone();
|
||||
this.guiItemMap.put(slot, guiItem);
|
||||
this.itemStackMap.put(slot, itemStack);
|
||||
final GuiItem setItem = this.getGuiItem(user, player, guiItem, itemStack);
|
||||
if (setItem == null) return;
|
||||
this.gui.updateItem(slot, setItem);
|
||||
}
|
||||
|
||||
public CosmeticGui copy() {
|
||||
return new CosmeticGui(
|
||||
this.plugin,
|
||||
|
||||
@@ -57,10 +57,14 @@ public class CosmeticsMenu {
|
||||
|
||||
if (cosmeticGui instanceof final DyeSelectorGui dyeSelectorGui) {
|
||||
dyeSelectorGui.getGui(user, user.getLastSetItem().getType()).open(humanEntity);
|
||||
user.setOpenGui(dyeSelectorGui);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cosmeticGui != null) cosmeticGui.open(user, player);
|
||||
if (cosmeticGui != null) {
|
||||
user.setOpenGui(cosmeticGui);
|
||||
cosmeticGui.open(user, player);
|
||||
}
|
||||
}
|
||||
|
||||
public void openDefault(final HumanEntity humanEntity) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import io.github.fisher2911.hmccosmetics.config.CosmeticSettings;
|
||||
import io.github.fisher2911.hmccosmetics.config.Settings;
|
||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
||||
import io.github.fisher2911.hmccosmetics.gui.CosmeticGui;
|
||||
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
|
||||
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -42,6 +43,8 @@ public class User {
|
||||
private boolean hasArmorStand;
|
||||
private final int armorStandId;
|
||||
|
||||
private CosmeticGui openGui;
|
||||
|
||||
// List of players that are currently viewing the armorstand
|
||||
private final Set<UUID> viewing = new HashSet<>();
|
||||
|
||||
@@ -221,6 +224,15 @@ public class User {
|
||||
this.hasArmorStand = false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CosmeticGui getOpenGui() {
|
||||
return openGui;
|
||||
}
|
||||
|
||||
public void setOpenGui(final CosmeticGui openGui) {
|
||||
this.openGui = openGui;
|
||||
}
|
||||
|
||||
public boolean hasArmorStand() {
|
||||
return hasArmorStand;
|
||||
}
|
||||
|
||||
193
common/src/main/resources/menus/test-menu.yml
Normal file
193
common/src/main/resources/menus/test-menu.yml
Normal file
@@ -0,0 +1,193 @@
|
||||
title: "<white>" # GUI Title
|
||||
rows: 5 # Rows in the GUI
|
||||
items:
|
||||
1: # GUI Slot number
|
||||
material: LEATHER_HORSE_ARMOR # Also supports Oraxen items! Format: "oraxen:item_name"
|
||||
name: "<rainbow>Colorful Hat</rainbow>"
|
||||
lore: # Lore displayed when the player owns the item
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore: # Lore displayed when the player does not have the correct permission.
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 2 # CustomModelData Number
|
||||
type: HAT
|
||||
dyeable: true # Enables dyeable item feature
|
||||
color: # Sets default color for item. Uses RGB format.
|
||||
red: 5
|
||||
green: 230
|
||||
blue: 100
|
||||
action: # See how the action system works on the wiki
|
||||
any:
|
||||
open-menu: dye-menu
|
||||
permission: "cosmetics.colorful_hat" # Can be anything you want.
|
||||
id: colorful_hat # Internal identifier. Can be anything you want.
|
||||
2:
|
||||
material: PAPER
|
||||
name: "<blue>Backpack"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 4
|
||||
type: BACKPACK
|
||||
permission: ""
|
||||
id: backpack
|
||||
action:
|
||||
# when the action should be run
|
||||
# equip = when a cosmetic is equipped
|
||||
# remove = when a cosmetic is removed
|
||||
# any all = default, does not need to be specified
|
||||
equip:
|
||||
# click type
|
||||
any:
|
||||
send-message: "on equip"
|
||||
remove:
|
||||
any:
|
||||
send-message: "on-remove"
|
||||
any:
|
||||
# send a message
|
||||
send-message: "Test first message"
|
||||
# send a command, format is <sender:command>
|
||||
# senders can be player or console
|
||||
send-command: "player:give %player% diamond"
|
||||
# list of messages
|
||||
send-messages:
|
||||
- "Message 1"
|
||||
- "Message 2"
|
||||
# list of commands
|
||||
send-commands:
|
||||
- "player:help"
|
||||
- "console:give %player% gold_ingot"
|
||||
# set items in the specified slots in the inventory
|
||||
# works with all actions
|
||||
# sets items in the next inventory if open-menu is specified
|
||||
set-items:
|
||||
12:
|
||||
material: PAPER
|
||||
name: "<red>Backpack"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 4
|
||||
type: BACKPACK
|
||||
permission: ""
|
||||
id: backpack
|
||||
action:
|
||||
any:
|
||||
send-message: "It worked?"
|
||||
set-items:
|
||||
12:
|
||||
material: PAPER
|
||||
name: "<rainbow>Backpack"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 4
|
||||
type: BACKPACK
|
||||
permission: ""
|
||||
id: backpack
|
||||
|
||||
3:
|
||||
material: PAPER
|
||||
name: "<blue>Lantern Cosmetic"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 5
|
||||
type: OFF_HAND
|
||||
permission: ""
|
||||
id: lantern_cosmetic
|
||||
4:
|
||||
material: PAPER
|
||||
name: "<blue>Baseball Hat"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 6
|
||||
type: HAT
|
||||
permission: ""
|
||||
id: baseball_hat
|
||||
5:
|
||||
material: DIAMOND_CHESTPLATE
|
||||
name: "<blue>Cosmetic Chestplate"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
type: CHEST_PLATE
|
||||
permission: ""
|
||||
id: chestplate
|
||||
6:
|
||||
material: DIAMOND_LEGGINGS
|
||||
name: "<blue>Cosmetic Leggings"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
type: PANTS
|
||||
permission: ""
|
||||
id: pants
|
||||
7:
|
||||
material: DIAMOND_BOOTS
|
||||
name: "<blue>Cosmetic Boots"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
type: BOOTS
|
||||
permission: ""
|
||||
id: boots
|
||||
37:
|
||||
material: PAPER
|
||||
name: "<#40B7D6>Previous Page"
|
||||
amount: 1
|
||||
model-data: 1
|
||||
action:
|
||||
any:
|
||||
open-menu: menu-2
|
||||
40:
|
||||
material: PAPER
|
||||
name: "<rainbow>Customization Menu</rainbow>"
|
||||
amount: 1
|
||||
model-data: 3
|
||||
action:
|
||||
any:
|
||||
open-menu: dye-menu
|
||||
43:
|
||||
material: PAPER
|
||||
name: "<#40B7D6>Next Page"
|
||||
amount: 1
|
||||
model-data: 2
|
||||
action:
|
||||
any:
|
||||
open-menu: menu-2
|
||||
Reference in New Issue
Block a user