diff --git a/example-datapack/data/example/gui/new_features_demo.json b/example-datapack/data/example/gui/new_features_demo.json index 7c6c527..e1284a2 100644 --- a/example-datapack/data/example/gui/new_features_demo.json +++ b/example-datapack/data/example/gui/new_features_demo.json @@ -1,215 +1,210 @@ { - "title": "§dMaster GUI Demo §8— {player}", + "title": "§6New Features §8— {player} §7[{page1}/{pages}]", "rows": 4, "tick_rate": 20, - "close_on_move": true, "filler": { - "item": "minecraft:gray_stained_glass_pane", + "item": "minecraft:black_stained_glass_pane", "name": " ", "glint": false, "hide_tooltip": true }, "on_open": [ - { "type": "set_var", "var": "counter", "value": "1" } + { "type": "sound", "value": "minecraft:block.note_block.pling:1.0:1.2" } ], "buttons": [ { - "slot": 4, - "item": "minecraft:player_head", - "name": "§d★ Master GUI API Demo ★", + "slot": 4, "page": 0, + "item": "minecraft:nether_star", + "name": "§6New Features Demo", + "glint": true, "lore": [ - "§7Current value: §f{var:counter}", - "§7Current Score (Coins): §e{score:coins}", - "§7XP Level: §a{player}'s level", - "§7Auto-refreshing every 1 second (tick_rate: 20)", - "§7Closes automatically if you walk away (close_on_move: true)", - "§7Empty slots are automatically filled (filler object)" - ] + "§7This GUI demonstrates the 3 new features:", + "§a► give_item §8— item ver", + "§b► broadcast §8— tüm sunucuya mesaj", + "§e► Yeni placeholder'lar", + " ", + "§8{gui} §7Page {page1}/{pages}" + ], + "actions": [{ "type": "sound", "value": "minecraft:entity.experience_orb.pickup" }] }, + { - "slot": 10, - "item": "minecraft:lime_concrete", - "name": "§a1. Dynamic Stack Size & Action Delays", - "amount": "{var:counter}", + "slot": 10, "page": 0, + "item": "minecraft:diamond", + "name": "§b► give_item §7— Tek Item", "lore": [ - "§7Updates slot item count based on a variable,", - "§7completely flicker-free!", - "§7Next count: §f{var:counter}", - "§7Increments by 1, waits 20 ticks (1s), then plays sound!" + "§7Envantere 1 diamond ver.", + "§8Syntax: give_item:", + " ", + "§aKliğa bas!" ], "actions": [ - { "type": "add_var", "var": "counter", "value": "1" }, - { "type": "action_bar", "value": "§aCounter updated to {var:counter}! Sound playing in 1s..." }, - { "type": "refresh" }, - { "type": "sound", "value": "minecraft:entity.experience_orb.pickup:0.5:1.2", "delay": 20 } + { "type": "give_item", "value": "minecraft:diamond" }, + { "type": "sound", "value": "minecraft:entity.item.pickup" }, + { "type": "action_bar", "value": "§b+1 Diamond alındı!" } ] }, + { - "slot": 12, - "item": "minecraft:diamond_sword", - "name": "§b2. Item Shop §a(Buy Iron)", + "slot": 12, "page": 0, + "item": "minecraft:emerald", + "name": "§a► give_item §7— Miktar ile", "lore": [ - "§7Cost: §e5 Gold Nuggets", - "§7Requires gold in inventory.", - "§aClick to purchase!" + "§7Envantere 8 emerald ver.", + "§8Syntax: give_item::", + " ", + "§aKliğa bas!" ], - "condition": { "type": "has_item", "value": "minecraft:gold_nugget:5" }, "actions": [ - { "type": "take_item", "value": "minecraft:gold_nugget:5" }, - { "type": "run_command", "value": "give @s minecraft:iron_ingot", "run_with": "console" }, - { "type": "sound", "value": "minecraft:entity.villager.yes" }, - { "type": "action_bar", "value": "§aPurchase successful!" }, - { "type": "refresh" } + { "type": "give_item", "value": "minecraft:emerald:8" }, + { "type": "sound", "value": "minecraft:entity.item.pickup" }, + { "type": "action_bar", "value": "§a+8 Emerald alındı!" } ] }, + { - "slot": 12, - "item": "minecraft:barrier", - "name": "§c2. Item Shop §7(Locked)", + "slot": 14, "page": 0, + "item": "minecraft:beacon", + "name": "§e► broadcast §7— Chat", "lore": [ - "§7Cost: §e5 Gold Nuggets", - "§cYou do not have enough Gold Nuggets!" + "§7Tüm oyunculara chat mesajı gönder.", + "§8Syntax: broadcast:", + " ", + "§eKliğa bas!" ], - "condition": { "type": "not_item", "value": "minecraft:gold_nugget:5" }, "actions": [ - { "type": "sound", "value": "minecraft:entity.villager.no" }, - { "type": "action_bar", "value": "§cInsufficient funds!" } + { "type": "broadcast", "value": "§6[Duyuru] §f{player} §7bir GUI'den mesaj gönderdi!" }, + { "type": "sound", "value": "minecraft:block.note_block.bell:1.0:1.0" }, + { "type": "action_bar", "value": "§eMesaj tüm oyunculara gönderildi." } ] }, + { - "slot": 14, - "item": "minecraft:gold_block", - "name": "§e5. Scoreboard & ActionBar Support", + "slot": 16, "page": 0, + "item": "minecraft:end_crystal", + "name": "§d► broadcast §7— Action Bar", + "glint": true, "lore": [ - "§7Directly modifies your scoreboard!", - "§7Left-Click: §a+10 Coins", - "§7Right-Click: §c-10 Coins", - "§7Current Coins: §e{score:coins}" + "§7Tüm oyuncuların action bar'ına mesaj.", + "§8Syntax: broadcast:actionbar:", + " ", + "§dKliğa bas!" ], "actions": [ - { "type": "add_score", "value": "coins:10" }, - { "type": "sound", "value": "minecraft:entity.experience_orb.pickup" }, - { "type": "action_bar", "value": "§a+10 Coins added!" }, - { "type": "refresh" } - ], - "click_type": "left" + { "type": "broadcast", "value": "actionbar:§d✦ §f{player} §7bir şey yaptı! §d✦" }, + { "type": "sound", "value": "minecraft:entity.ender_dragon.growl:0.3:1.8" }, + { "type": "action_bar", "value": "§dAction bar mesajı gönderildi." } + ] }, + { - "slot": 14, - "item": "minecraft:gold_block", - "name": "§e5. Scoreboard & ActionBar Support", - "lore": [ - "§7Directly modifies your scoreboard!", - "§7Left-Click: §a+10 Coins", - "§7Right-Click: §c-10 Coins", - "§7Current Coins: §e{score:coins}" - ], + "slot": 31, "page": 0, + "item": "minecraft:arrow", + "name": "§7Sonraki Sayfa →", + "lore": ["§8Page {page1}/{pages}"], "actions": [ - { "type": "sub_score", "value": "coins:10" }, - { "type": "sound", "value": "minecraft:block.anvil.land:0.2:1.5" }, - { "type": "action_bar", "value": "§c-10 Coins removed!" }, - { "type": "refresh" } - ], - "click_type": "right" + { "type": "sound", "value": "minecraft:item.book.page_turn" }, + { "type": "next_page" } + ] }, + { - "slot": 16, - "item": "minecraft:netherite_sword", - "name": "§c6. Hiding Additional Tooltips", + "slot": 4, "page": 1, + "item": "minecraft:experience_bottle", + "name": "§eYeni Placeholder'lar", "lore": [ - "§7Cleans up sword damage modifiers", - "§7using hide_additional_tooltip: true!" - ], - "hide_additional_tooltip": true + "§7Bu sayfa yeni {health}/{food}/{level}/{xp}", + "§7placeholder'larını gösterir.", + " ", + "§c❤ Can: §f{health} / {max_health}", + "§6🍗 Açlık: §f{food} / 20", + "§a✦ Level: §f{level}", + "§b★ XP: §f{xp}", + " ", + "§8tick_rate:20 — değerler otomatik güncellenir." + ], + "actions": [{ "type": "sound", "value": "minecraft:entity.experience_orb.pickup:0.5:1.5" }] }, + { - "slot": 20, - "item": "minecraft:brewing_stand", - "name": "§d8. Status Effect Controller", + "slot": 10, "page": 1, + "item": "minecraft:red_dye", + "name": "§c❤ Can: §f{health} / {max_health}", "lore": [ - "§7Left-Click: §bReceive Speed II (15s)", - "§7Right-Click: §cCure Effects (Drink Milk)" - ], - "actions": [ - { "type": "add_effect", "value": "minecraft:speed:15:1:false" }, - { "type": "sound", "value": "minecraft:entity.generic.drink" }, - { "type": "action_bar", "value": "§bSpeed II Effect granted!" } + "§7Anlık HP durumu.", + "§8Placeholder: §c{health} §8ve §c{max_health}" ], - "click_type": "left" + "actions": [{ "type": "action_bar", "value": "§c❤ Can: {health}/{max_health}" }] }, + { - "slot": 20, - "item": "minecraft:brewing_stand", - "name": "§d8. Status Effect Controller", + "slot": 12, "page": 1, + "item": "minecraft:cooked_beef", + "name": "§6🍗 Açlık: §f{food} / 20", "lore": [ - "§7Left-Click: §bReceive Speed II (15s)", - "§7Right-Click: §cCure Effects (Drink Milk)" + "§7Anlık açlık seviyesi.", + "§8Placeholder: §6{food}" ], - "actions": [ - { "type": "clear_effects" }, - { "type": "sound", "value": "minecraft:entity.cow.milk" }, - { "type": "action_bar", "value": "§cAll effects cleared!" } - ], - "click_type": "right" + "actions": [{ "type": "action_bar", "value": "§6🍗 Açlık: {food}/20" }] }, + { - "slot": 22, + "slot": 14, "page": 1, "item": "minecraft:experience_bottle", - "name": "§a7. Experience Check §7(Level >= 30)", + "name": "§a✦ Level: §f{level}", "lore": [ - "§7Only players with XP Level >= 30", - "§7can click this button!" + "§7Anlık XP level.", + "§8Placeholder: §a{level}" ], - "condition": { "type": "level_gt", "value": "29" }, - "actions": [ - { "type": "sound", "value": "minecraft:entity.player.levelup" }, - { "type": "action_bar", "value": "§aCongratulations! Level check passed." } - ] + "actions": [{ "type": "action_bar", "value": "§a✦ Level: {level}" }] }, + { - "slot": 22, - "item": "minecraft:glass_bottle", - "name": "§c7. Experience Check §7(Locked)", + "slot": 16, "page": 1, + "item": "minecraft:green_dye", + "name": "§b★ XP: §f{xp}", "lore": [ - "§cYour level is below 30!", - "§7This feature is locked." + "§7Toplam XP puanı.", + "§8Placeholder: §b{xp}" ], - "condition": { "type": "level_lt", "value": "30" }, - "actions": [ - { "type": "sound", "value": "minecraft:entity.enderman.teleport:0.5:0.5" }, - { "type": "action_bar", "value": "§cYou must be at least level 30!" } - ] + "actions": [{ "type": "action_bar", "value": "§b★ Total XP: {xp}" }] }, + { - "slot": 24, - "item": "minecraft:book", - "name": "§b3. Multi-Value Custom Model Data", + "slot": 22, "page": 1, + "item": "minecraft:golden_apple", + "name": "§c► give_item §8+ Placeholder Combo", "lore": [ - "§7Advanced 1.21.4+ floats/flags/strings/colors" + "§7Give item ve placeholder birlikte:", + "§7Can durumuna göre mesaj + apple ver.", + " ", + "§c❤ Şu anki can: {health}/{max_health}", + "§aKliğa bas — apple al!" ], - "custom_model_data": { - "floats": [42.5], - "flags": [true, false], - "strings": ["demo_tag"], - "colors": [16711680] - } + "actions": [ + { "type": "give_item", "value": "minecraft:golden_apple" }, + { "type": "sound", "value": "minecraft:entity.item.pickup" }, + { "type": "action_bar", "value": "§c❤ {health}/{max_health} §7can ile golden apple aldın!" } + ] }, + { - "slot": 26, - "item": "minecraft:stick", - "name": "§b3. Custom Item Model", - "lore": [ - "§7Applies custom item_model ID", - "§7directly to the stick item." - ], - "item_model": "my_pack:item/custom_sword" + "slot": 27, "page": 1, + "item": "minecraft:arrow", + "name": "§7← Önceki Sayfa", + "lore": ["§8Page {page1}/{pages}"], + "actions": [ + { "type": "sound", "value": "minecraft:item.book.page_turn" }, + { "type": "prev_page" } + ] }, + { - "slot": 31, + "slot": 35, "page": 1, "item": "minecraft:barrier", - "name": "§cClose", + "name": "§cKapat", "actions": [ - { "type": "sound", "value": "minecraft:ui.button.click" }, + { "type": "sound", "value": "minecraft:block.wooden_button.click_off" }, { "type": "close" } ] } diff --git a/src/main/java/dev/toolkitmc/guiapi/command/GuiCommand.java b/src/main/java/dev/toolkitmc/guiapi/command/GuiCommand.java index cd77250..eb6739a 100644 --- a/src/main/java/dev/toolkitmc/guiapi/command/GuiCommand.java +++ b/src/main/java/dev/toolkitmc/guiapi/command/GuiCommand.java @@ -72,6 +72,19 @@ public static void register(CommandDispatcher dispatcher) { .then(CommandManager.literal("help") .executes(GuiCommand::showHelp)) + .then(CommandManager.literal("info") + .then(CommandManager.argument("id", IdentifierArgumentType.identifier()) + .suggests((ctx, builder) -> { + String input = builder.getRemainingLowerCase(); + GuiRegistry.INSTANCE.getAll().keySet().stream() + .map(Identifier::toString) + .filter(s -> s.contains(input)) + .forEach(builder::suggest); + return builder.buildFuture(); + }) + .executes(GuiCommand::infoGui)) + ) + .then(CommandManager.literal("var") .then(CommandManager.literal("get") .then(CommandManager.argument("target", EntityArgumentType.player()) @@ -175,10 +188,61 @@ private static int varClear(CommandContext ctx) throws com. return count; } + private static int infoGui(CommandContext ctx) { + Identifier id = IdentifierArgumentType.getIdentifier(ctx, "id"); + GuiDefinition def = GuiRegistry.INSTANCE.get(id).orElse(null); + if (def == null) { + ctx.getSource().sendError(Text.literal("[GuiAPI] GUI not found: " + id)); + return 0; + } + + StringBuilder sb = new StringBuilder(); + sb.append("[GuiAPI] Info: ").append(id).append("\n"); + sb.append(" rows=").append(def.getRows()) + .append(" pages=").append(def.getPageCount()) + .append(" buttons=").append(def.getButtons().size()) + .append(" tick_rate=").append(def.getTickRate()) + .append(" close_on_move=").append(def.isCloseOnMove()) + .append(" container=").append(def.getContainerType().name().toLowerCase()) + .append("\n"); + sb.append(" title: ").append(def.getTitle()).append("\n"); + sb.append(" on_open actions: ").append(def.getOnOpen().size()).append("\n"); + sb.append(" on_close actions: ").append(def.getOnClose().size()).append("\n"); + def.getFiller().ifPresent(f -> + sb.append(" filler: ").append(f.item()).append("\n")); + + for (int p = 0; p < def.getPageCount(); p++) { + java.util.List pageBtns = def.getButtonsForPage(p); + sb.append(" [page ").append(p).append("] ").append(pageBtns.size()).append(" button(s)"); + for (GuiDefinition.Button b : pageBtns) { + sb.append("\n slot=").append(b.slot()); + if (b.toggle().isPresent()) { + sb.append(" [toggle tag=").append(b.toggle().get().tag()).append("]"); + } else { + sb.append(" item=").append(b.item()); + if (!b.actions().isEmpty()) { + sb.append(" actions=["); + b.actions().forEach(a -> sb.append(a.type().name().toLowerCase()).append(",")); + sb.deleteCharAt(sb.length() - 1); + sb.append("]"); + } + } + b.condition().ifPresent(c -> + sb.append(" cond=").append(c.type().name().toLowerCase()).append(":").append(c.value())); + } + sb.append("\n"); + } + + String out = sb.toString().trim(); + ctx.getSource().sendFeedback(() -> Text.literal(out), false); + return 1; + } + private static int showHelp(CommandContext ctx) { String help = "[GuiAPI] Commands (permission level 2):\n" + " /guiapi open [targets] - Open a GUI for yourself or target players\n" + + " /guiapi info - Show detailed info about a loaded GUI\n" + " /guiapi list - List all loaded GUI definitions\n" + " /guiapi reload - Reload all datapack resources (including GUIs)\n" + " /guiapi var get - Get a runtime variable\n" + @@ -197,7 +261,13 @@ private static int showHelp(CommandContext ctx) { " var_eq | var_gt | var_lt | var_set\n" + " actions: run_command | close | open_gui | message | sound\n" + " next_page | prev_page | goto_page\n" + - " set_var | add_var | sub_var | reset_var | clear_vars"; + " set_var | add_var | sub_var | reset_var | clear_vars\n" + + " give_item | broadcast\n" + + "\n" + + "give_item value: [:] e.g. minecraft:diamond:3\n" + + "broadcast value: or actionbar:\n" + + "\n" + + "Extra placeholders: {health} {max_health} {food} {level} {xp}"; ctx.getSource().sendFeedback(() -> Text.literal(help), false); return 1; } diff --git a/src/main/java/dev/toolkitmc/guiapi/config/GuiApiConfig.java b/src/main/java/dev/toolkitmc/guiapi/config/GuiApiConfig.java index 80a57a4..b7bfc95 100644 --- a/src/main/java/dev/toolkitmc/guiapi/config/GuiApiConfig.java +++ b/src/main/java/dev/toolkitmc/guiapi/config/GuiApiConfig.java @@ -44,6 +44,9 @@ public final class GuiApiConfig { private int soundVolume = 100; // 9. New Config private String commandExecuteMode = "CHAT"; // 10. New Config + private boolean allowGiveItem = true; // 11. give_item action guard + private boolean allowBroadcast = true; // 12. broadcast action guard + private GuiApiConfig() {} // ── Load / Save ────────────────────────────────────────────────────────── @@ -92,6 +95,10 @@ public void load() { soundVolume = Math.clamp(obj.get("sound_volume").getAsInt(), 0, 100); if (obj.has("command_execute_mode")) commandExecuteMode = obj.get("command_execute_mode").getAsString(); + if (obj.has("allow_give_item")) + allowGiveItem = obj.get("allow_give_item").getAsBoolean(); + if (obj.has("allow_broadcast")) + allowBroadcast = obj.get("allow_broadcast").getAsBoolean(); } catch (IOException e) { GuiApiMod.LOGGER.error("[GuiAPI] Failed to load config: {}", e.getMessage()); @@ -117,6 +124,8 @@ public void save() { obj.addProperty("chat_prefix", chatPrefix); obj.addProperty("sound_volume", soundVolume); obj.addProperty("command_execute_mode", commandExecuteMode); + obj.addProperty("allow_give_item", allowGiveItem); + obj.addProperty("allow_broadcast", allowBroadcast); try { Files.writeString(CONFIG_PATH, GSON.toJson(obj)); } catch (IOException e) { @@ -174,4 +183,10 @@ public void save() { public String getCommandExecuteMode() { return commandExecuteMode; } public void setCommandExecuteMode(String v) { commandExecuteMode = v; } + + public boolean isAllowGiveItem() { return allowGiveItem; } + public void setAllowGiveItem(boolean v) { allowGiveItem = v; } + + public boolean isAllowBroadcast() { return allowBroadcast; } + public void setAllowBroadcast(boolean v) { allowBroadcast = v; } } diff --git a/src/main/java/dev/toolkitmc/guiapi/gui/BarrelGuiHandler.java b/src/main/java/dev/toolkitmc/guiapi/gui/BarrelGuiHandler.java index aae8b28..bda5a72 100644 --- a/src/main/java/dev/toolkitmc/guiapi/gui/BarrelGuiHandler.java +++ b/src/main/java/dev/toolkitmc/guiapi/gui/BarrelGuiHandler.java @@ -517,6 +517,11 @@ static String resolve(String text, ServerPlayerEntity player, text = text.replace("{page}", String.valueOf(page)); text = text.replace("{page1}", String.valueOf(page + 1)); text = text.replace("{pages}", String.valueOf(def.getPageCount())); + text = text.replace("{health}", String.valueOf((int) player.getHealth())); + text = text.replace("{max_health}", String.valueOf((int) player.getMaxHealth())); + text = text.replace("{food}", String.valueOf(player.getHungerManager().getFoodLevel())); + text = text.replace("{level}", String.valueOf(player.experienceLevel)); + text = text.replace("{xp}", String.valueOf(player.totalExperience)); // {score:objective} int idx; @@ -930,10 +935,84 @@ static boolean executeAction(ServerPlayerEntity player, GuiDefinition def, } player.clearStatusEffects(); } + case GIVE_ITEM -> { + // Syntax: [:] + // Example: "minecraft:diamond:3" or "minecraft:diamond" + if (!dev.toolkitmc.guiapi.config.GuiApiConfig.INSTANCE.isAllowGiveItem()) { + if (!dev.toolkitmc.guiapi.config.GuiApiConfig.INSTANCE.isMuteClickErrors()) + GuiApiMod.LOGGER.warn("[GuiAPI] give_item action is disabled in config."); + break; + } + String resolved = resolve(action.value(), player, def, currentPage); + giveItemToPlayer(player, resolved); + } + case BROADCAST -> { + // Syntax: [actionbar:] + // Prefix "actionbar:" → send to every player's action bar + // No prefix → send to every player's chat + if (!dev.toolkitmc.guiapi.config.GuiApiConfig.INSTANCE.isAllowBroadcast()) { + if (!dev.toolkitmc.guiapi.config.GuiApiConfig.INSTANCE.isMuteClickErrors()) + GuiApiMod.LOGGER.warn("[GuiAPI] broadcast action is disabled in config."); + break; + } + String resolved = resolve(action.value(), player, def, currentPage); + boolean toActionBar = resolved.startsWith("actionbar:"); + String msg = toActionBar ? resolved.substring("actionbar:".length()) : resolved; + Text broadcastText = Text.literal(msg); + for (ServerPlayerEntity online : server.getPlayerManager().getPlayerList()) { + online.sendMessage(broadcastText, toActionBar); + } + } } return false; } + // ── Give item helper ────────────────────────────────────────────────────── + + /** + * Parses "{item_id}" or "{item_id}:{amount}" and gives the item to the player. + * Falls back to /give command for complex item strings containing NBT/components. + * Uses the Minecraft item registry for simple items. + */ + private static void giveItemToPlayer(ServerPlayerEntity player, String value) { + // Split off trailing amount if the last colon segment is a pure integer + // e.g. "minecraft:diamond:3" → item="minecraft:diamond", amount=3 + // "minecraft:stone" → item="minecraft:stone", amount=1 + String itemId = value; + int amount = 1; + int lastColon = value.lastIndexOf(':'); + if (lastColon > 0) { + String possibleAmount = value.substring(lastColon + 1); + // Make sure the segment before it still looks like a namespace:path + // (i.e., there is at least one earlier colon for the namespace) + int firstColon = value.indexOf(':'); + if (firstColon != lastColon) { + try { + amount = Math.clamp(Integer.parseInt(possibleAmount), 1, 64); + itemId = value.substring(0, lastColon); + } catch (NumberFormatException ignored) { + // The last segment is not a number — treat the whole string as item id + } + } + } + + Identifier id = Identifier.tryParse(itemId); + if (id != null && Registries.ITEM.containsId(id)) { + ItemStack stack = new ItemStack(Registries.ITEM.get(id), amount); + boolean inserted = player.getInventory().insertStack(stack); + if (!inserted) { + // Inventory full — drop at player's feet + player.dropItem(stack, false); + } + player.currentScreenHandler.sendContentUpdates(); + debug("give_item: player={} item={} x{}", player.getNameForScoreboard(), itemId, amount); + } else { + if (!dev.toolkitmc.guiapi.config.GuiApiConfig.INSTANCE.isMuteClickErrors()) { + GuiApiMod.LOGGER.warn("[GuiAPI] give_item: unknown item '{}', skipping.", itemId); + } + } + } + // ── Score helpers ───────────────────────────────────────────────────────── private static void modifyScore(ServerPlayerEntity player, String objectiveName, int val, ScoreModType modType) { diff --git a/src/main/java/dev/toolkitmc/guiapi/gui/GuiDefinition.java b/src/main/java/dev/toolkitmc/guiapi/gui/GuiDefinition.java index e50c1d1..034ed15 100644 --- a/src/main/java/dev/toolkitmc/guiapi/gui/GuiDefinition.java +++ b/src/main/java/dev/toolkitmc/guiapi/gui/GuiDefinition.java @@ -52,7 +52,8 @@ public enum ActionType { RUN_COMMAND, CLOSE, OPEN_GUI, MESSAGE, NEXT_PAGE, PREV_PAGE, GOTO_PAGE, SOUND, SET_VAR, ADD_VAR, SUB_VAR, RESET_VAR, CLEAR_VARS, REFRESH, TAKE_ITEM, SET_SCORE, ADD_SCORE, SUB_SCORE, ACTION_BAR, - ADD_EFFECT, REMOVE_EFFECT, CLEAR_EFFECTS, NONE, ANVIL_INPUT; + ADD_EFFECT, REMOVE_EFFECT, CLEAR_EFFECTS, NONE, ANVIL_INPUT, + GIVE_ITEM, BROADCAST; public static ActionType fromString(String s) { return switch (s.toLowerCase()) { @@ -80,6 +81,8 @@ public static ActionType fromString(String s) { case "clear_effects" -> CLEAR_EFFECTS; case "none" -> NONE; case "anvil_input" -> ANVIL_INPUT; + case "give_item" -> GIVE_ITEM; + case "broadcast" -> BROADCAST; default -> NONE; }; }