diff --git a/README.md b/README.md index 3f3267f..6f47248 100644 --- a/README.md +++ b/README.md @@ -5,15 +5,17 @@ LovelyDrop is a minecraft plugin that adds a drop system to a server. You can cu ## Features - The fully customizable GUI with items that can perform few actions when clicked - Set title and rows for menu - - Set display name and lore for menu item with 4 available placeholders + - Set display name and lore for menu item with 5 available placeholders - **{CHANCE}** - a chance of the item to drop - **{AMOUNT}** - a formatted amount of the item that could drop - **{EXPERIENCE}** - an experience that will be given to the player - **{SWITCH}** - text that will be shown depending on the drop switch status + - **{SWITCH_INVENTORY}** - text that will be shown depending on the inventory drop switch status - Set action that item should perform after being clicked - **NONE** - item will not do any action - **CLOSE_MENU** - menu will be closed - **SWITCH_DROP** - drop assigned to this menu item will be turned on/off + - **SWITCH_DROP_TO_INVENTORY** - drop assigned to this menu item will have its "drop to inventory" property switched - Set click types when to perform the specified action - **ALL** - action will be performed on any type of the click - **LEFT** - action will be performed on left click diff --git a/img/menu-preview.png b/img/menu-preview.png index 8d64c66..cdefe40 100644 Binary files a/img/menu-preview.png and b/img/menu-preview.png differ diff --git a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/LovelyDropPlugin.java b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/LovelyDropPlugin.java index 5e6d9c2..dfa7042 100644 --- a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/LovelyDropPlugin.java +++ b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/LovelyDropPlugin.java @@ -50,7 +50,7 @@ public void onEnable() { PluginManager pluginManager = this.getServer().getPluginManager(); - pluginManager.registerEvents(new UserListener(this.userCache), this); + pluginManager.registerEvents(new UserListener(this.userCache, this.itemCache), this); pluginManager.registerEvents(new DropListener(this.logger, this.itemCache, this.userCache), this); MenuService menuService = new MenuService(this.logger, this.menu, this.userCache); diff --git a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/drop/DropListener.java b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/drop/DropListener.java index 25521db..1c925f7 100644 --- a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/drop/DropListener.java +++ b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/drop/DropListener.java @@ -19,7 +19,10 @@ import io.github.zrdzn.minecraft.lovelydrop.item.ItemCache; import io.github.zrdzn.minecraft.lovelydrop.user.User; import io.github.zrdzn.minecraft.lovelydrop.user.UserCache; +import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -50,7 +53,9 @@ public DropListener(Logger logger, ItemCache itemCache, UserCache userCache) { public void onSourceBreak(BlockBreakEvent event) { Player player = event.getPlayer(); - Material source = event.getBlock().getType(); + Block block = event.getBlock(); + + Material source = block.getType(); // Get optional drops from source blocks. Set sourceDrops = this.itemCache.getDrops(source); @@ -98,11 +103,21 @@ public void onSourceBreak(BlockBreakEvent event) { droppedItemMeta.setLore(item.getLore()); droppedItem.setItemMeta(droppedItemMeta); - Map itemsLeft = player.getInventory().addItem(droppedItem); + World world = player.getWorld(); + + Location location = block.getLocation(); + + if (user.hasSwitchedInventoryDrop(item.getId())) { + Map itemsLeft = player.getInventory().addItem(droppedItem); + + // Drop items on the floor if player has full inventory. + itemsLeft.forEach((key, value) -> + world.dropItemNaturally(location, value)); + + return; + } - // Drop items on the floor if player has full inventory. - itemsLeft.forEach((key, value) -> - player.getWorld().dropItemNaturally(player.getEyeLocation(), value)); + world.dropItemNaturally(location, droppedItem); }); } diff --git a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/Menu.java b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/Menu.java index 82ef47d..b4bc4df 100644 --- a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/Menu.java +++ b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/Menu.java @@ -24,15 +24,17 @@ public class Menu { private final int rows; private final MenuFiller filler; private final Entry dropSwitch; + private final Entry inventoryDropSwitch; private final Entry amountFormat; private final List items; public Menu(String title, int rows, MenuFiller filler, Entry dropSwitch, - Entry amountFormat, List items) { + Entry inventoryDropSwitch, Entry amountFormat, List items) { this.title = title; this.rows = rows; this.filler = filler; this.dropSwitch = dropSwitch; + this.inventoryDropSwitch = inventoryDropSwitch; this.amountFormat = amountFormat; this.items = items; } @@ -53,6 +55,10 @@ public Entry getDropSwitch() { return this.dropSwitch; } + public Entry getInventoryDropSwitch() { + return this.inventoryDropSwitch; + } + public Entry getAmountFormat() { return this.amountFormat; } diff --git a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/MenuAction.java b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/MenuAction.java index da5c9b0..0ee32e3 100644 --- a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/MenuAction.java +++ b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/MenuAction.java @@ -19,6 +19,7 @@ public enum MenuAction { CLOSE_MENU, SWITCH_DROP, - NONE + NONE, + SWITCH_DROP_TO_INVENTORY } diff --git a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/MenuParser.java b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/MenuParser.java index 73abdd5..3147de8 100644 --- a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/MenuParser.java +++ b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/MenuParser.java @@ -73,6 +73,11 @@ public Menu parse(ConfigurationSection section) throws InvalidConfigurationExcep Entry dropSwitch = new AbstractMap.SimpleEntry<>(dropSwitchEnabled, dropSwitchDisabled); + String inventoryDropSwitchEnabled = LovelyDropPlugin.color(section.getString("inventory-drop-switch.enabled", "&aon")); + String inventoryDropSwitchDisabled = LovelyDropPlugin.color(section.getString("inventory-drop-switch.disabled", "&coff")); + + Entry inventoryDropSwitch = new AbstractMap.SimpleEntry<>(inventoryDropSwitchEnabled, inventoryDropSwitchDisabled); + String amountSingular = LovelyDropPlugin.color(section.getString("amount-format.singular", "&e{AMOUNT}")); String amountPlural = LovelyDropPlugin.color(section.getString("amount-format.plural", "&e{AMOUNT-MIN}&8-&e{AMOUNT-MAX}")); @@ -82,7 +87,7 @@ public Menu parse(ConfigurationSection section) throws InvalidConfigurationExcep List menuItems = menuItemParser.parseMany(section.getConfigurationSection("items")); - return new Menu(title, rows, filler, dropSwitch, amountFormat, menuItems); + return new Menu(title, rows, filler, dropSwitch, inventoryDropSwitch, amountFormat, menuItems); } } diff --git a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/MenuService.java b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/MenuService.java index c8d0f40..0d29c9f 100644 --- a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/MenuService.java +++ b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/menu/MenuService.java @@ -121,17 +121,23 @@ public boolean open(Player player) { .collect(Collectors.toList()); Entry dropSwitch = this.menu.getDropSwitch(); + Entry inventoryDropSwitch = this.menu.getInventoryDropSwitch(); GuiItem menuItem = ItemBuilder.from(item.getType()) .setName(item.getDisplayName()) .setLore(lore.stream() - .map(line -> line.replace("{SWITCH}", - !user.hasDisabledDrop(dropItem) ? dropSwitch.getKey() : dropSwitch.getValue())) + .map(line -> line + .replace("{SWITCH}", !user.hasDisabledDrop(dropItem) ? dropSwitch.getKey() : dropSwitch.getValue()) + .replace("{SWITCH_INVENTORY}", user.hasSwitchedInventoryDrop(dropItem.getId()) ? + inventoryDropSwitch.getKey() : + inventoryDropSwitch.getValue())) .collect(Collectors.toList())) .asGuiItem(); // Perform specific actions when player clicks the item. menuItem.setAction(event -> { + String itemId = dropItem.getId(); + if (!actions.containsKey(ClickType.UNKNOWN)) { ClickType click = event.getClick(); @@ -146,6 +152,8 @@ public boolean open(Player player) { } else { user.disableDrop(dropItem); } + } else if (action == MenuAction.SWITCH_DROP_TO_INVENTORY) { + user.switchInventoryDrop(itemId, !user.hasSwitchedInventoryDrop(itemId)); } } } else { @@ -159,13 +167,18 @@ public boolean open(Player player) { } else { user.disableDrop(dropItem); } + } else if (action == MenuAction.SWITCH_DROP_TO_INVENTORY) { + user.switchInventoryDrop(itemId, !user.hasSwitchedInventoryDrop(itemId)); } } ItemStack actionItem = ItemBuilder.from(menuItem.getItemStack()) .setLore(lore.stream() - .map(line -> line.replace("{SWITCH}", - !user.hasDisabledDrop(dropItem) ? dropSwitch.getKey() : dropSwitch.getValue())) + .map(line -> line + .replace("{SWITCH}", !user.hasDisabledDrop(dropItem) ? dropSwitch.getKey() : dropSwitch.getValue()) + .replace("{SWITCH_INVENTORY}", user.hasSwitchedInventoryDrop(dropItem.getId()) ? + inventoryDropSwitch.getKey() : + inventoryDropSwitch.getValue())) .collect(Collectors.toList())) .build(); diff --git a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/user/User.java b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/user/User.java index df4deaf..5d671c7 100644 --- a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/user/User.java +++ b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/user/User.java @@ -17,6 +17,9 @@ import io.github.zrdzn.minecraft.lovelydrop.item.Item; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; import java.util.Set; import java.util.UUID; @@ -24,10 +27,12 @@ public class User { private final UUID id; private final Set disabledDrops; + private final Map inventoryDrops; - public User(UUID id, Set disabledDrops) { + public User(UUID id) { this.id = id; - this.disabledDrops = disabledDrops; + this.disabledDrops = new HashSet<>(); + this.inventoryDrops = new HashMap<>(); } public UUID getId() { @@ -50,4 +55,27 @@ public Set getDisabledDrops() { return this.disabledDrops; } + public void addInventoryDrop(Item item, boolean initialValue) { + this.inventoryDrops.put(item, initialValue); + } + + public void switchInventoryDrop(String itemId, boolean newValue) throws IllegalArgumentException { + Item item = this.inventoryDrops.keySet().stream() + .filter(key -> key.getId().equals(itemId)) + .findAny() + .orElseThrow(() -> + new IllegalArgumentException(String.format("Drop with the specified item id does not exist (%s).", itemId))); + + this.inventoryDrops.replace(item, newValue); + } + + public boolean hasSwitchedInventoryDrop(String itemId) throws IllegalArgumentException { + return this.inventoryDrops.entrySet().stream() + .filter((entry) -> entry.getKey().getId().equals(itemId)) + .findAny() + .orElseThrow(() -> + new IllegalArgumentException(String.format("Drop with the specified item id does not exist (%s).", itemId))) + .getValue(); + } + } diff --git a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/user/UserListener.java b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/user/UserListener.java index 2266003..eeea173 100644 --- a/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/user/UserListener.java +++ b/plugin/src/main/java/io/github/zrdzn/minecraft/lovelydrop/user/UserListener.java @@ -15,27 +15,32 @@ */ package io.github.zrdzn.minecraft.lovelydrop.user; +import io.github.zrdzn.minecraft.lovelydrop.item.ItemCache; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; -import java.util.HashSet; import java.util.UUID; public class UserListener implements Listener { private final UserCache userCache; + private final ItemCache itemCache; - public UserListener(UserCache userCache) { + public UserListener(UserCache userCache, ItemCache itemCache) { this.userCache = userCache; + this.itemCache = itemCache; } @EventHandler public void onJoin(PlayerJoinEvent event) { UUID playerId = event.getPlayer().getUniqueId(); - this.userCache.addUser(playerId, new User(playerId, new HashSet<>())); + User user = new User(playerId); + this.itemCache.getDrops().values().forEach(items -> items.forEach(item -> user.addInventoryDrop(item, false))); + + this.userCache.addUser(playerId, user); } @EventHandler diff --git a/plugin/src/main/resources/config.yml b/plugin/src/main/resources/config.yml index 03d7a0b..22db28d 100644 --- a/plugin/src/main/resources/config.yml +++ b/plugin/src/main/resources/config.yml @@ -30,6 +30,15 @@ menu: disabled: "&coff" + # Text placeholder which stands for {SWITCH_INVENTORY} that can be used in items section. + inventory-drop-switch: + # Used when the drop to inventory is switched on for the player. + enabled: "&eon" + + # Used when the drop to inventory is switched off for the player. + disabled: "&coff" + + # Text placeholder which stands for {AMOUNT} that could be used in items section. amount-format: # Used when the drop's amount is one number. @@ -41,10 +50,11 @@ menu: # All items that will appear in the menu. There are 3 available types of items in the menu. # They are based on the action that they do when they are clicked. Actions: - # NONE - it will not do anything; - # CLOSE_MENU - it will close the menu; - # SWITCH_DROP - it will switch drop on/off (id of the item here must equal to the id in the 'drops' section - # to make this work, otherwise it will not recognise the drop that it should switch on/off). + # NONE - it will not do anything; + # CLOSE_MENU - it will close the menu; + # SWITCH_DROP - it will switch drop on/off (id of the item here must equal to the id in the 'drops' section + # to make this work, otherwise it will not recognise the drop that it should switch on/off); + # SWITCH_DROP_TO_INVENTORY - it will switch whether to drop the item to the inventory or on the floor # # click-action section contains key, value fields where the key is the specified field in the # https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/inventory/ClickType.html. If you want to perform an action @@ -68,11 +78,12 @@ menu: # - "&7Click to close the menu." # # Available placeholders: - # {CHANCE} - a chance of the item to drop; - # {AMOUNT} - a formatted text that will display amount/s of the drop, it can be configured - # in the amount-format section; - # {EXPERIENCE} - an experience that will be given to the player on the successful drop; - # {SWITCH} - text that will be shown depending on the drop switch status + # {CHANCE} - a chance of the item to drop; + # {AMOUNT} - a formatted text that will display amount/s of the drop, it can be configured + # in the amount-format section; + # {EXPERIENCE} - an experience that will be given to the player on the successful drop; + # {SWITCH} - text that will be shown depending on the drop switch status; + # {SWITCH_INVENTORY} - text that will be shown depending on the inventory drop switch status items: close: type: barrier @@ -93,7 +104,7 @@ menu: click-action: LEFT: SWITCH_DROP - RIGHT: CLOSE_MENU + RIGHT: SWITCH_DROP_TO_INVENTORY slot: row: 2 @@ -106,14 +117,18 @@ menu: - " &6Amount: {AMOUNT}" - " &6Experience: &e{EXPERIENCE}" - " &6Status: {SWITCH}" + - " &6To inventory: {SWITCH_INVENTORY}" - "" - - "&aClick to switch the drop." + - "&8-------------------------------------" + - " &aLeft click to switch the drop." + - " &eRight click to switch the inventory drop." + - "&8-------------------------------------" diamond: type: diamond click-action: LEFT: SWITCH_DROP - RIGHT: CLOSE_MENU + RIGHT: SWITCH_DROP_TO_INVENTORY slot: row: 2 @@ -126,14 +141,18 @@ menu: - " &6Amount: {AMOUNT}" - " &6Experience: &e{EXPERIENCE}" - " &6Status: {SWITCH}" + - " &6To inventory: {SWITCH_INVENTORY}" - "" - - "&aClick to switch the drop." + - "&8-------------------------------------" + - " &aLeft click to switch the drop." + - " &eRight click to switch the inventory drop." + - "&8-------------------------------------" tnt: type: tnt click-action: LEFT: SWITCH_DROP - RIGHT: CLOSE_MENU + RIGHT: SWITCH_DROP_TO_INVENTORY slot: row: 2 @@ -146,14 +165,18 @@ menu: - " &6Amount: {AMOUNT}" - " &6Experience: &e{EXPERIENCE}" - " &6Status: {SWITCH}" + - " &6To inventory: {SWITCH_INVENTORY}" - "" - - "&aClick to switch the drop." + - "&8-------------------------------------" + - " &aLeft click to switch the drop." + - " &eRight click to switch the inventory drop." + - "&8-------------------------------------" emerald: type: emerald click-action: LEFT: SWITCH_DROP - RIGHT: CLOSE_MENU + RIGHT: SWITCH_DROP_TO_INVENTORY slot: row: 2 @@ -166,14 +189,18 @@ menu: - " &6Amount: {AMOUNT}" - " &6Experience: &e{EXPERIENCE}" - " &6Status: {SWITCH}" + - " &6To inventory: {SWITCH_INVENTORY}" - "" - - "&aClick to switch the drop." + - "&8-------------------------------------" + - " &aLeft click to switch the drop." + - " &eRight click to switch the inventory drop." + - "&8-------------------------------------" obsidian: type: obsidian click-action: LEFT: SWITCH_DROP - RIGHT: CLOSE_MENU + RIGHT: SWITCH_DROP_TO_INVENTORY slot: row: 2 @@ -186,8 +213,12 @@ menu: - " &6Amount: {AMOUNT}" - " &6Experience: &e{EXPERIENCE}" - " &6Status: {SWITCH}" + - " &6To inventory: {SWITCH_INVENTORY}" - "" - - "&aClick to switch the drop." + - "&8-------------------------------------" + - " &aLeft click to switch the drop." + - " &eRight click to switch the inventory drop." + - "&8-------------------------------------"