diff --git a/TODO.md b/TODO.md
deleted file mode 100644
index c8c6461..0000000
--- a/TODO.md
+++ /dev/null
@@ -1,2 +0,0 @@
-- [ ] Block-Replacements are created even when a block is already queued for replacement. This should not happen!
-- [ ] It should be possible to enable random respawning for blocks within certain regions marked by a specific flag (ouroboros-mines-random?)
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 1dba1e1..ad2de02 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
dev.th3shadowbroker.spigot
OuroborosMines
- 1.7.1-SNAPSHOT
+ 1.8.0-SNAPSHOT
${project.artifactId}
@@ -63,7 +63,7 @@
org.spigotmc
spigot-api
- 1.15.1-R0.1-SNAPSHOT
+ 1.16.2-R0.1-SNAPSHOT
provided
diff --git a/src/main/java/dev/th3shadowbroker/ouroboros/mines/OuroborosMines.java b/src/main/java/dev/th3shadowbroker/ouroboros/mines/OuroborosMines.java
index 7ca7ede..efda054 100644
--- a/src/main/java/dev/th3shadowbroker/ouroboros/mines/OuroborosMines.java
+++ b/src/main/java/dev/th3shadowbroker/ouroboros/mines/OuroborosMines.java
@@ -22,11 +22,9 @@
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.flags.StateFlag;
import dev.th3shadowbroker.ouroboros.mines.commands.OmCommand;
+import dev.th3shadowbroker.ouroboros.mines.drops.DropManager;
import dev.th3shadowbroker.ouroboros.mines.exceptions.InvalidMineMaterialException;
-import dev.th3shadowbroker.ouroboros.mines.listeners.BlockBreakListener;
-import dev.th3shadowbroker.ouroboros.mines.listeners.DepositDiscoveryListener;
-import dev.th3shadowbroker.ouroboros.mines.listeners.ExperienceListener;
-import dev.th3shadowbroker.ouroboros.mines.listeners.TimeSkipListener;
+import dev.th3shadowbroker.ouroboros.mines.listeners.*;
import dev.th3shadowbroker.ouroboros.mines.thirdparty.JobsRebornSupport;
import dev.th3shadowbroker.ouroboros.mines.thirdparty.PlaceholderAPISupport;
import dev.th3shadowbroker.ouroboros.mines.thirdparty.QuestsSupport;
@@ -42,6 +40,7 @@
import org.th3shadowbroker.ouroboros.update.comparison.Comparator;
import org.th3shadowbroker.ouroboros.update.spiget.SpigetUpdater;
+import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
@@ -64,6 +63,8 @@ public class OuroborosMines extends JavaPlugin {
private AnnouncementManager announcementManager;
+ private DropManager dropManager;
+
private boolean worldGuardFound = false;
@Override
@@ -105,10 +106,13 @@ public void onEnable() {
getServer().getPluginManager().registerEvents( new DepositDiscoveryListener(), this );
getServer().getPluginManager().registerEvents( new ExperienceListener(), this );
getServer().getPluginManager().registerEvents( new TimeSkipListener(), this );
+ getServer().getPluginManager().registerEvents( new PlayerInteractListener(), this );
announcementManager = new AnnouncementManager();
announcementManager.createTasks();
+ dropManager = new DropManager(new File(getDataFolder(), "drops.yml"));
+
getCommand("om").setExecutor(new OmCommand());
checkForSupportedPlugins();
@@ -211,7 +215,15 @@ private void updateConfig() {
"autoPickup",
"openingHours",
"timezone",
- "placeholders"
+ "placeholders",
+ "chat.messages.reloadingDropGroups",
+ "chat.messages.reloadedDropGroups",
+ "chat.messages.awaitingRightClick",
+ "chat.messages.awaitingRightClickCancelled",
+ "chat.messages.dropGroupCreated",
+ "chat.messages.dropGroupExists",
+ "chat.messages.missingDropGroupName",
+ "chat.messages.consoleNotAllowed"
);
pathsToCopy.forEach(path -> {
if (!getConfig().isSet(path)) {
@@ -271,5 +283,9 @@ public TaskManager getTaskManager() {
public AnnouncementManager getAnnouncementManager() {
return announcementManager;
}
-
+
+ public DropManager getDropManager() {
+ return dropManager;
+ }
+
}
diff --git a/src/main/java/dev/th3shadowbroker/ouroboros/mines/commands/OmCommand.java b/src/main/java/dev/th3shadowbroker/ouroboros/mines/commands/OmCommand.java
index 8c5a27e..cfdb029 100644
--- a/src/main/java/dev/th3shadowbroker/ouroboros/mines/commands/OmCommand.java
+++ b/src/main/java/dev/th3shadowbroker/ouroboros/mines/commands/OmCommand.java
@@ -22,6 +22,7 @@
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import dev.th3shadowbroker.ouroboros.mines.OuroborosMines;
+import dev.th3shadowbroker.ouroboros.mines.drops.DropGroupCreator;
import dev.th3shadowbroker.ouroboros.mines.util.Permissions;
import dev.th3shadowbroker.ouroboros.mines.util.RegionConfiguration;
import dev.th3shadowbroker.ouroboros.mines.util.TemplateMessage;
@@ -37,7 +38,7 @@
public class OmCommand implements CommandExecutor {
- private final String consoleNotAllowed = TemplateMessage.from("chat.messages.consoleOnly").colorize().toString();
+ private final String consoleNotAllowed = TemplateMessage.from("chat.messages.consoleNotAllowed").colorize().toString();
private final OuroborosMines plugin = OuroborosMines.INSTANCE;
@@ -95,6 +96,9 @@ public boolean onCommand(CommandSender sender, Command cmd, String cmdLabel, Str
plugin.getMaterialManager().reloadRegionConfigurations();
sender.sendMessage(TemplateMessage.from("chat.messages.reloadedRegionConfigurations").insert("count", String.valueOf(plugin.getMaterialManager().getMineableMaterialOverrides().size())).colorize().toString());
plugin.getAnnouncementManager().flush();
+ sender.sendMessage(TemplateMessage.from("chat.messages.reloadingDropGroups").colorize().toString());
+ plugin.getDropManager().reloadGroups();
+ sender.sendMessage(TemplateMessage.from("chat.messages.reloadedDropGroups").insert("count", String.valueOf(plugin.getDropManager().getGroups().length)).colorize().toString());
} catch (Exception ex) {
sender.sendMessage(TemplateMessage.from("chat.messages.error").colorize().insert("error", ex.getMessage()).toString());
}
@@ -103,6 +107,38 @@ public boolean onCommand(CommandSender sender, Command cmd, String cmdLabel, Str
}
break;
+ case "dropgroup":
+ case "dg":
+ if (sender.hasPermission(Permissions.COMMAND_DROP_GROUP.permission)) {
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+
+ if (args.length >= 2) {
+ String dropGroupName = args[1];
+
+ // Drop group does not exist
+ if (!OuroborosMines.INSTANCE.getDropManager().getDropGroup(dropGroupName).isPresent()) {
+ DropGroupCreator.awaitCreation(player, dropGroupName);
+ player.sendMessage(TemplateMessage.from("chat.messages.awaitingRightClick").colorize().toString());
+ } else {
+ player.sendMessage(TemplateMessage.from("chat.messages.dropGroupExists").insert("name", dropGroupName).colorize().toString());
+ }
+ } else {
+ if (DropGroupCreator.creationPending(player)) {
+ DropGroupCreator.clearCreationStatus(player);
+ sender.sendMessage(TemplateMessage.from("chat.messages.awaitingRightClickCancelled").colorize().toString());
+ } else {
+ sender.sendMessage(TemplateMessage.from("chat.messages.missingDropGroupName").colorize().toString());
+ }
+ }
+ } else {
+ sender.sendMessage(consoleNotAllowed);
+ }
+ } else {
+ sender.sendMessage(cmd.getPermissionMessage());
+ }
+ break;
+
default:
sender.sendMessage(TemplateMessage.from("chat.messages.unrecognizedArgument").colorize().toString());
sender.sendMessage(cmd.getUsage());
diff --git a/src/main/java/dev/th3shadowbroker/ouroboros/mines/drops/Drop.java b/src/main/java/dev/th3shadowbroker/ouroboros/mines/drops/Drop.java
new file mode 100644
index 0000000..77b51d1
--- /dev/null
+++ b/src/main/java/dev/th3shadowbroker/ouroboros/mines/drops/Drop.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2020 Jens Fischer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package dev.th3shadowbroker.ouroboros.mines.drops;
+
+import dev.th3shadowbroker.ouroboros.mines.util.Range;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.inventory.ItemStack;
+
+public class Drop {
+
+ private final ItemStack itemStack;
+
+ private final double dropChance;
+
+ private final Range dropAmount;
+
+ public Drop(ItemStack itemStack, double dropChance, Range dropAmount) {
+ this.itemStack = itemStack;
+ this.dropChance = dropChance;
+ this.dropAmount = dropAmount;
+ }
+
+ public ItemStack getItemStack() {
+ return itemStack;
+ }
+
+ public double getDropChance() {
+ return dropChance;
+ }
+
+ public Range getDropAmount() {
+ return dropAmount;
+ }
+
+ public ItemStack drawDropstack() {
+ ItemStack dropStack = itemStack.clone();
+ dropStack.setAmount(dropAmount.isRange() ? dropAmount.getRandomWithin() : dropAmount.getMin());
+ return dropStack;
+ }
+
+ public static Drop fromSection(ConfigurationSection section) {
+ ItemStack itemStack = section.getItemStack("item");
+ double dropChance = section.getDouble("chance", 1);
+ Range dropAmount = Range.fromString(section.getString("amount", "1"));
+ return new Drop(itemStack, dropChance, dropAmount);
+ }
+
+}
diff --git a/src/main/java/dev/th3shadowbroker/ouroboros/mines/drops/DropGroup.java b/src/main/java/dev/th3shadowbroker/ouroboros/mines/drops/DropGroup.java
new file mode 100644
index 0000000..0156280
--- /dev/null
+++ b/src/main/java/dev/th3shadowbroker/ouroboros/mines/drops/DropGroup.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2020 Jens Fischer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package dev.th3shadowbroker.ouroboros.mines.drops;
+
+import org.bukkit.inventory.ItemStack;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+public class DropGroup {
+
+ private final List drops;
+
+ private final boolean multidrop;
+
+ public DropGroup(List drops, boolean multidrop) {
+ this.drops = drops;
+ this.multidrop = multidrop;
+ }
+
+ public boolean isValid() {
+ return multidrop || drops.stream().mapToDouble(Drop::getDropChance).sum() <= 1;
+ }
+
+ public List getDrops() {
+ return drops;
+ }
+
+ public boolean isMultidrop() {
+ return multidrop;
+ }
+
+ private ItemStack[] drawMultidrop() {
+ final List drops = new ArrayList<>();
+ this.drops.forEach(
+ drop -> {
+
+ // Drop chance 100 or higher
+ if (drop.getDropChance() >= 1) {
+ drops.add(drop.drawDropstack());
+
+ // Drop chance below 100
+ } else {
+ Random rnd = new Random();
+ boolean shallDrop = ((double) rnd.nextInt(100) / 100) <= drop.getDropChance();
+ if (shallDrop) {
+ drops.add(drop.drawDropstack());
+ }
+ }
+
+ }
+ );
+ return drops.stream().toArray(ItemStack[]::new);
+ }
+
+ private ItemStack[] drawSingledrop() {
+ ItemStack dropStack = null;
+ Random rnd = new Random();
+
+ double drawnChance = ((double) rnd.nextInt(100) / 100);
+ double offset = 0;
+
+ for (Drop drop : drops) {
+ boolean shallDrop = drawnChance <= drop.getDropChance() + offset;
+
+ if (shallDrop) {
+ dropStack = drop.drawDropstack();
+ break;
+ } else {
+ offset += drop.getDropChance();
+ }
+ }
+
+ return dropStack == null ? new ItemStack[0] : new ItemStack[]{ dropStack };
+ }
+
+ public ItemStack[] drawDrops() {
+ return multidrop ? drawMultidrop() : drawSingledrop();
+ }
+
+}
diff --git a/src/main/java/dev/th3shadowbroker/ouroboros/mines/drops/DropGroupCreator.java b/src/main/java/dev/th3shadowbroker/ouroboros/mines/drops/DropGroupCreator.java
new file mode 100644
index 0000000..fdf5f92
--- /dev/null
+++ b/src/main/java/dev/th3shadowbroker/ouroboros/mines/drops/DropGroupCreator.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2020 Jens Fischer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package dev.th3shadowbroker.ouroboros.mines.drops;
+
+import dev.th3shadowbroker.ouroboros.mines.OuroborosMines;
+import dev.th3shadowbroker.ouroboros.mines.util.Range;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.metadata.FixedMetadataValue;
+import org.bukkit.metadata.MetadataValue;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class DropGroupCreator {
+
+ private static final String META_AWAITING_RIGHT_CLICK = "OM_AWAITING_RIGHT_CLICK";
+
+ private static final String META_DROP_GROUP_NAME = "OM_DROP_GROUP_NAME";
+
+ public static void awaitCreation(Player player, String dropGroupName) {
+ if (!creationPending(player)) {
+ player.setMetadata(META_AWAITING_RIGHT_CLICK, new FixedMetadataValue(OuroborosMines.INSTANCE, true));
+ player.setMetadata(META_DROP_GROUP_NAME, new FixedMetadataValue(OuroborosMines.INSTANCE, dropGroupName));
+ }
+ }
+
+ public static void clearCreationStatus(Player player) {
+ player.removeMetadata(META_AWAITING_RIGHT_CLICK, OuroborosMines.INSTANCE);
+ player.removeMetadata(META_DROP_GROUP_NAME, OuroborosMines.INSTANCE);
+ }
+
+ public static boolean creationPending(Player player) {
+ return player.hasMetadata(META_AWAITING_RIGHT_CLICK) && player.hasMetadata(META_DROP_GROUP_NAME);
+ }
+
+ public static String getDropGroupName(Player player) {
+ List values = player.getMetadata(META_DROP_GROUP_NAME);
+ return values.isEmpty() ? null : values.get(0).asString();
+ }
+
+ public static void saveDropGroup(Inventory inventory, String dropGroupName) throws IOException {
+ DropManager dropManager = OuroborosMines.INSTANCE.getDropManager();
+
+ ConfigurationSection section = dropManager.getConfiguration().createSection(dropGroupName);
+ section.set("multidrop", true);
+
+ ConfigurationSection dropsSection = section.createSection("drops");
+
+ List drops = Arrays.stream(inventory.getContents()).filter(itemStack -> itemStack != null).map(itemStack -> new Drop(itemStack.clone(), 1, new Range(1, 1))).collect(Collectors.toList());
+ for (int i = 0; i < drops.size(); i++) {
+ ConfigurationSection dropSection = dropsSection.createSection(String.valueOf(i));
+
+ Drop drop = drops.get(i);
+ drop.getItemStack().setAmount(1);
+
+ dropSection.set("chance", drop.getDropChance());
+ dropSection.set("amount", Integer.valueOf(drop.getDropAmount().toString()));
+ dropSection.set("item", drop.getItemStack());
+ }
+
+ dropManager.getConfiguration().save(dropManager.getFile());
+ }
+
+}
diff --git a/src/main/java/dev/th3shadowbroker/ouroboros/mines/drops/DropManager.java b/src/main/java/dev/th3shadowbroker/ouroboros/mines/drops/DropManager.java
new file mode 100644
index 0000000..b0c8d72
--- /dev/null
+++ b/src/main/java/dev/th3shadowbroker/ouroboros/mines/drops/DropManager.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2020 Jens Fischer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package dev.th3shadowbroker.ouroboros.mines.drops;
+
+import dev.th3shadowbroker.ouroboros.mines.OuroborosMines;
+import org.bukkit.Material;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.inventory.ItemStack;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.logging.Logger;
+
+public class DropManager {
+
+ private final File file;
+
+ private final FileConfiguration configuration;
+
+ private final Map dropGroups;
+
+ private final Logger log;
+
+ public DropManager(File dropFile) {
+ this.dropGroups = new HashMap<>();
+ this.file = dropFile;
+ this.log = OuroborosMines.INSTANCE.getLogger();
+ if (!dropFile.exists()) {
+ try {
+ boolean dropFileCreated = dropFile.createNewFile();
+ if (dropFileCreated) log.info("Drop file created.");
+ } catch (IOException ex) {
+ log.warning("Failed to create drop file!");
+ }
+ }
+ this.configuration = YamlConfiguration.loadConfiguration(dropFile);
+ loadGroups();
+ }
+
+ private void loadGroups() {
+ log.info(String.format("Loading drops from %s", file.getAbsolutePath()));
+
+ for (String groupName : configuration.getKeys(false)) {
+ ConfigurationSection groupSection = configuration.getConfigurationSection(groupName);
+ if (groupSection == null) continue;
+
+ try {
+ ConfigurationSection dropSection = groupSection.getConfigurationSection("drops");
+ boolean multidrop = groupSection.getBoolean("multidrop", false);
+
+ final List drops = new ArrayList<>();
+ dropSection.getKeys(false).forEach( key -> {
+ drops.add(Drop.fromSection(dropSection.getConfigurationSection(key)));
+ } );
+
+ dropGroups.put(groupName, new DropGroup(drops, multidrop));
+ } catch (Exception ex) {
+ log.warning(String.format("Unable to evaluate the %s section of %s. Please check the wiki. Skipping.", groupName, file.getAbsolutePath()));
+ }
+ }
+
+ log.info(String.format("Loaded %s drop groups!", dropGroups.size()));
+ }
+
+ public void reloadGroups() {
+ dropGroups.clear();
+ loadGroups();
+ }
+
+ public void addGroup(String groupName, DropGroup group) {
+ dropGroups.put(groupName, group);
+ }
+
+ public Optional getDropGroup(String groupName) {
+ return Optional.ofNullable(dropGroups.getOrDefault(groupName, null));
+ }
+
+ public String[] getGroupNames() {
+ return dropGroups.keySet().stream().toArray(String[]::new);
+ }
+
+ public DropGroup[] getGroups() {
+ return dropGroups.values().stream().toArray(DropGroup[]::new);
+ }
+
+ public File getFile() {
+ return file;
+ }
+
+ public FileConfiguration getConfiguration() {
+ return configuration;
+ }
+}
diff --git a/src/main/java/dev/th3shadowbroker/ouroboros/mines/listeners/BlockBreakListener.java b/src/main/java/dev/th3shadowbroker/ouroboros/mines/listeners/BlockBreakListener.java
index a4e5893..84b9311 100644
--- a/src/main/java/dev/th3shadowbroker/ouroboros/mines/listeners/BlockBreakListener.java
+++ b/src/main/java/dev/th3shadowbroker/ouroboros/mines/listeners/BlockBreakListener.java
@@ -27,13 +27,13 @@
import dev.th3shadowbroker.ouroboros.mines.events.MaterialMinedEvent;
import dev.th3shadowbroker.ouroboros.mines.util.*;
import org.bukkit.Bukkit;
+import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
-import java.util.Collection;
import java.util.Map;
import java.util.Optional;
@@ -46,7 +46,6 @@ public class BlockBreakListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
public void onBlockBreak(BlockBreakEvent event) {
Optional blockRegions = WorldUtils.getBlockRegions(event.getBlock());
-
if ( blockRegions.isPresent() && blockRegions.get().testState(null, OuroborosMines.FLAG)) {
Optional minedMaterial = plugin.getMaterialManager().getMaterialProperties(event.getBlock().getType(), WorldUtils.getTopRegion(blockRegions.get()).get(), BukkitAdapter.adapt(event.getBlock().getWorld()));
if (minedMaterial.isPresent()) {
@@ -85,7 +84,7 @@ public void onBlockBreak(BlockBreakEvent event) {
//If rich
if (MetaUtils.isRich(event.getBlock())) {
//event.getBlock().breakNaturally(event.getPlayer().getInventory().getItemInMainHand());
- breakBlock(event, event.getPlayer().getInventory().getItemInMainHand());
+ breakBlock(event, minedMaterial.get(), event.getPlayer().getInventory().getItemInMainHand());
event.getBlock().setType(minedMaterial.get().getMaterial());
MetaUtils.decreaseRichness(event.getBlock());
@@ -107,7 +106,7 @@ public void onBlockBreak(BlockBreakEvent event) {
//Break it! Replace it!
//event.getBlock().breakNaturally(event.getPlayer().getInventory().getItemInMainHand());
- breakBlock(event, event.getPlayer().getInventory().getItemInMainHand());
+ breakBlock(event, minedMaterial.get(), event.getPlayer().getInventory().getItemInMainHand());
event.getBlock().setType(minedMaterial.get().getReplacement());
}
@@ -115,11 +114,23 @@ public void onBlockBreak(BlockBreakEvent event) {
}
}
- private void breakBlock(BlockBreakEvent event, ItemStack tool) {
+ private void breakBlock(BlockBreakEvent event, MineableMaterial mineableMaterial, ItemStack tool) {
if (!autoPickup) {
- event.getBlock().breakNaturally(event.getPlayer().getInventory().getItemInMainHand());
+ // Check for drop group
+ if (mineableMaterial.getDropGroup().isPresent()) {
+ event.setDropItems(false);
+
+ for (ItemStack drop : mineableMaterial.getDropGroup().get().drawDrops()) {
+ event.getBlock().getWorld().dropItem(event.getBlock().getLocation(), drop);
+ }
+
+ // No drop-group assigned
+ } else {
+ event.getBlock().breakNaturally(event.getPlayer().getInventory().getItemInMainHand());
+ }
} else {
- ItemStack[] drops = event.getBlock().getDrops(event.getPlayer().getInventory().getItemInMainHand()).stream().toArray(ItemStack[]::new);
+ // Modified in favour of drop feature
+ ItemStack[] drops = mineableMaterial.getDropGroup().isPresent() ? mineableMaterial.getDropGroup().get().drawDrops() : event.getBlock().getDrops(event.getPlayer().getInventory().getItemInMainHand()).stream().toArray(ItemStack[]::new);
Map overflow = event.getPlayer().getInventory().addItem(drops);
if (overflow.size() > 0) {
overflow.forEach((slot, item) -> event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), item));
diff --git a/src/main/java/dev/th3shadowbroker/ouroboros/mines/listeners/PlayerInteractListener.java b/src/main/java/dev/th3shadowbroker/ouroboros/mines/listeners/PlayerInteractListener.java
new file mode 100644
index 0000000..d2af082
--- /dev/null
+++ b/src/main/java/dev/th3shadowbroker/ouroboros/mines/listeners/PlayerInteractListener.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2020 Jens Fischer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package dev.th3shadowbroker.ouroboros.mines.listeners;
+
+import dev.th3shadowbroker.ouroboros.mines.OuroborosMines;
+import dev.th3shadowbroker.ouroboros.mines.drops.DropGroupCreator;
+import dev.th3shadowbroker.ouroboros.mines.util.TemplateMessage;
+import org.bukkit.Material;
+import org.bukkit.block.Container;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.player.PlayerInteractEvent;
+
+import java.io.IOException;
+
+public class PlayerInteractListener implements Listener {
+
+ @EventHandler
+ public void onPlayerInteract(PlayerInteractEvent event) {
+ if (event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getClickedBlock().getType() == Material.CHEST) {
+ if (DropGroupCreator.creationPending(event.getPlayer())) {
+ Player player = event.getPlayer();
+ Container container = (Container) event.getClickedBlock().getState();
+ String dropGroupName = DropGroupCreator.getDropGroupName(event.getPlayer());
+
+ // Drop group does not exist
+ if (!OuroborosMines.INSTANCE.getDropManager().getDropGroup(dropGroupName).isPresent()) {
+ try {
+ DropGroupCreator.saveDropGroup(container.getInventory(), dropGroupName);
+ player.sendMessage(TemplateMessage.from("chat.messages.dropGroupCreated").insert("name", dropGroupName).colorize().toString());
+ } catch (IOException ex) {
+ player.sendMessage(TemplateMessage.from("chat.messages.error").insert("error", ex.getMessage()).colorize().toString());
+ }
+
+ // Done!
+ DropGroupCreator.clearCreationStatus(player);
+ // Drop group exists
+ } else {
+ player.sendMessage(TemplateMessage.from("chat.messages.dropGroupExists").insert("name", dropGroupName).colorize().toString());
+ }
+
+ event.setCancelled(true);
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/dev/th3shadowbroker/ouroboros/mines/util/MineableMaterial.java b/src/main/java/dev/th3shadowbroker/ouroboros/mines/util/MineableMaterial.java
index fd71238..e170831 100644
--- a/src/main/java/dev/th3shadowbroker/ouroboros/mines/util/MineableMaterial.java
+++ b/src/main/java/dev/th3shadowbroker/ouroboros/mines/util/MineableMaterial.java
@@ -20,6 +20,7 @@
package dev.th3shadowbroker.ouroboros.mines.util;
import dev.th3shadowbroker.ouroboros.mines.OuroborosMines;
+import dev.th3shadowbroker.ouroboros.mines.drops.DropGroup;
import dev.th3shadowbroker.ouroboros.mines.exceptions.InvalidMineMaterialException;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
@@ -47,7 +48,9 @@ public class MineableMaterial {
private final Range depositExperience;
- public MineableMaterial(Material material, Material[] replacements, Range cooldown, double richChance, Range richAmount, Range experience, Range depositExperience) {
+ private final String dropGroup;
+
+ public MineableMaterial(Material material, Material[] replacements, Range cooldown, double richChance, Range richAmount, Range experience, Range depositExperience, String dropGroup) {
this.material = material;
this.replacements = replacements;
this.cooldown = cooldown;
@@ -55,6 +58,7 @@ public MineableMaterial(Material material, Material[] replacements, Range cooldo
this.richAmount = richAmount;
this.experience = experience;
this.depositExperience = depositExperience;
+ this.dropGroup = dropGroup;
}
public Material getMaterial() {
@@ -109,6 +113,10 @@ public Material getReplacement() {
return replacements[replRandom.nextInt(replacements.length)];
}
+ public Optional getDropGroup() {
+ return dropGroup == null ? Optional.empty() : OuroborosMines.INSTANCE.getDropManager().getDropGroup(dropGroup);
+ }
+
public static MineableMaterial fromSection(ConfigurationSection section) throws InvalidMineMaterialException {
//Parse material
Optional material = Optional.ofNullable(Material.getMaterial(section.getName().toUpperCase()));
@@ -173,6 +181,9 @@ public static MineableMaterial fromSection(ConfigurationSection section) throws
}
}
+ //Parse drop group
+ String dropGroup = section.getString("dropGroup", null);
+
return new MineableMaterial(
//Material and replacements
@@ -185,8 +196,10 @@ public static MineableMaterial fromSection(ConfigurationSection section) throws
//Add range-values
richAmount == null ? Range.zero() : richAmount,
experience == null ? Range.zero() : experience,
- depositExperience == null ? Range.zero() : depositExperience
+ depositExperience == null ? Range.zero() : depositExperience,
+ //Drop group
+ dropGroup
);
}
diff --git a/src/main/java/dev/th3shadowbroker/ouroboros/mines/util/Permissions.java b/src/main/java/dev/th3shadowbroker/ouroboros/mines/util/Permissions.java
index a1c8fb5..3d6b9fb 100644
--- a/src/main/java/dev/th3shadowbroker/ouroboros/mines/util/Permissions.java
+++ b/src/main/java/dev/th3shadowbroker/ouroboros/mines/util/Permissions.java
@@ -27,7 +27,8 @@ public enum Permissions {
COMMAND_ROOT("ouroboors.mines.command.*"),
COMMAND_INFO("ouroboros.mines.command.info"),
COMMAND_CUSTOMIZE("ouroboros.mines.command.customize"),
- COMMAND_RELOAD("ouroboros.mines.command.reload");
+ COMMAND_RELOAD("ouroboros.mines.command.reload"),
+ COMMAND_DROP_GROUP("ouroboros.mines.command.dropgroup");
public final String name;
diff --git a/src/main/java/dev/th3shadowbroker/ouroboros/mines/util/Range.java b/src/main/java/dev/th3shadowbroker/ouroboros/mines/util/Range.java
index 9833252..73cd753 100644
--- a/src/main/java/dev/th3shadowbroker/ouroboros/mines/util/Range.java
+++ b/src/main/java/dev/th3shadowbroker/ouroboros/mines/util/Range.java
@@ -64,7 +64,7 @@ public int getRandomWithin() {
@Override
public String toString() {
- return String.format("%s-%s", min, max);
+ return isRange() ? String.format("%s-%s", min, max) : String.valueOf(min);
}
public static Range zero() {
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index 11dec09..46daf98 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -9,14 +9,21 @@ default: false
chat:
prefix: '&9[OM]'
messages:
- consoleOnly: "&cThis command can not be executed from console!"
+ awaitingRightClick: "&2Right-click the chest you want to create the drop group from or type &e/om dg&2 to cancel!"
+ awaitingRightClickCancelled: "&cDrop group creation cancelled!"
+ consoleNotAllowed: "&cThis command can not be executed from console!"
+ dropGroupCreated: "&2Saved drop group &e%name%"
+ dropGroupExists: "&cThere's already a drop-group name &e%name%&c!"
unrecognizedArgument: "&cUnrecognized argument"
+ missingDropGroupName: "&cMissing drop-group name!"
regionCustomize: "&2A new configuration file for &b%region%&2 has been created!"
regionAlreadyCustomized: "&cThere's already a configuration file for this region!"
regionNotFound: "&cNo region found at your position!"
reloadingConfig: "&2Reloading configuration..."
reloadingRegionConfigurations: "&2Reloading region-configurations..."
reloadedRegionConfigurations: "&2Loaded %count% region-specific configurations"
+ reloadingDropGroups: "&2Reloading drop groups..."
+ reloadedDropGroups: "&2Loaded %count% drop groups"
worldNotFound: "&cWorld &e%world% &cnot found!"
depositDiscovered: "&2You've discovered a %size% &e%material%&2 deposit!"
depositSizes:
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index c3aa965..bd235bf 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -10,7 +10,7 @@ api-version: 1.13
commands:
om:
description: General command for ${plugin.name}
- usage: /om [customize:reload]
+ usage: /om [customize:reload] [world:name] [region]
permission-message: §cYou're not allowed to do this!
permissions:
@@ -27,6 +27,7 @@ permissions:
ouroboros.mines.command.info: true
ouroboros.mines.command.customize: true
ouroboros.mines.command.reload: true
+ ouroboros.mines.command.dropgroup: true
ouroboros.mines.command.info:
default: true
@@ -35,4 +36,7 @@ permissions:
default: op
ouroboros.mines.command.reload:
- default: op
\ No newline at end of file
+ default: op
+
+ ouroboros.mines.command.dropgroup:
+ default: op