From c02a5b1751fc641e4cec88dd7170b1586aceceb1 Mon Sep 17 00:00:00 2001 From: Brianna Date: Mon, 8 Jul 2019 12:39:57 -0400 Subject: [PATCH] Added lootables. --- .gitlab-ci.yml | 2 +- .../ultimatestacker/UltimateStacker.java | 12 +- .../listeners/DeathListeners.java | 26 +- .../listeners/SpawnerListeners.java | 66 -- .../ultimatestacker/lootables/Loot.java | 169 ++++ .../lootables/LootBuilder.java | 88 ++ .../lootables/LootManager.java | 839 ++++++++++++++++++ .../ultimatestacker/lootables/Lootable.java | 32 + .../utils/settings/Setting.java | 5 +- 9 files changed, 1167 insertions(+), 72 deletions(-) delete mode 100644 src/main/java/com/songoda/ultimatestacker/listeners/SpawnerListeners.java create mode 100644 src/main/java/com/songoda/ultimatestacker/lootables/Loot.java create mode 100644 src/main/java/com/songoda/ultimatestacker/lootables/LootBuilder.java create mode 100644 src/main/java/com/songoda/ultimatestacker/lootables/LootManager.java create mode 100644 src/main/java/com/songoda/ultimatestacker/lootables/Lootable.java diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e0aaf80..c0539c1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,7 +4,7 @@ stages: variables: name: "UltimateStacker" path: "/builds/$CI_PROJECT_PATH" - version: "1.5.11" + version: "1.6" build: stage: build diff --git a/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java b/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java index 65132e4..71f1dc8 100644 --- a/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java +++ b/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java @@ -8,6 +8,7 @@ import com.songoda.ultimatestacker.hologram.HologramHolographicDisplays; import com.songoda.ultimatestacker.hook.StackerHook; import com.songoda.ultimatestacker.hook.hooks.JobsHook; import com.songoda.ultimatestacker.listeners.*; +import com.songoda.ultimatestacker.lootables.LootManager; import com.songoda.ultimatestacker.spawner.SpawnerStack; import com.songoda.ultimatestacker.spawner.SpawnerStackManager; import com.songoda.ultimatestacker.storage.Storage; @@ -50,6 +51,7 @@ public class UltimateStacker extends JavaPlugin { private SettingsManager settingsManager; private EntityStackManager entityStackManager; private SpawnerStackManager spawnerStackManager; + private LootManager lootManager; private CommandManager commandManager; private StackingTask stackingTask; private Hologram hologram; @@ -90,6 +92,11 @@ public class UltimateStacker extends JavaPlugin { this.commandManager = new CommandManager(this); + this.lootManager = new LootManager(); + + lootManager.createDefaultLootables(); + lootManager.loadLootables(); + for (EntityType value : EntityType.values()) { if (value.isSpawnable() && value.isAlive() && !value.toString().contains("ARMOR")) { mobFile.getConfig().addDefault("Mobs." + value.name() + ".Enabled", true); @@ -168,7 +175,6 @@ public class UltimateStacker extends JavaPlugin { pluginManager.registerEvents(new ItemListeners(this), this); pluginManager.registerEvents(new TameListeners(this), this); pluginManager.registerEvents(new SheepDyeListeners(this), this); - pluginManager.registerEvents(new SpawnerListeners(this), this); if (Setting.CLEAR_LAG.getBoolean() && pluginManager.isPluginEnabled("ClearLag")) pluginManager.registerEvents(new ClearLagListeners(this), this); @@ -260,6 +266,10 @@ public class UltimateStacker extends JavaPlugin { return commandManager; } + public LootManager getLootManager() { + return lootManager; + } + public EntityStackManager getEntityStackManager() { return entityStackManager; } diff --git a/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java b/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java index 3f6b197..13ef55f 100644 --- a/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java +++ b/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java @@ -1,13 +1,16 @@ package com.songoda.ultimatestacker.listeners; import com.songoda.ultimatestacker.UltimateStacker; -import com.songoda.ultimatestacker.utils.Methods; +import com.songoda.ultimatestacker.utils.settings.Setting; +import org.bukkit.Material; +import org.bukkit.entity.Pig; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.inventory.ItemStack; -import java.util.ArrayList; +import java.util.List; public class DeathListeners implements Listener { @@ -19,8 +22,25 @@ public class DeathListeners implements Listener { @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onEntityDeath(EntityDeathEvent event) { + List items = Setting.CUSTOM_DROPS.getBoolean() + ? instance.getLootManager().getDrops(event.getEntity()) : event.getDrops(); + + if (items.size() != 0) { + if (event.getEntity() instanceof Pig && ((Pig) event.getEntity()).hasSaddle()) + event.getEntity().getWorld().dropItemNaturally(event.getEntity().getLocation(), + new ItemStack(Material.SADDLE)); + + event.getDrops().clear(); + } else + items = event.getDrops(); + + for (ItemStack item : items) { + if (item == null) continue; + event.getEntity().getWorld().dropItemNaturally(event.getEntity().getLocation(), item); + } + if (instance.getEntityStackManager().isStacked(event.getEntity())) instance.getEntityStackManager().getStack(event.getEntity()) - .onDeath(event.getEntity(), new ArrayList<>(event.getDrops()), event.getDroppedExp()); + .onDeath(event.getEntity(), items, event.getDroppedExp()); } } diff --git a/src/main/java/com/songoda/ultimatestacker/listeners/SpawnerListeners.java b/src/main/java/com/songoda/ultimatestacker/listeners/SpawnerListeners.java deleted file mode 100644 index 4e1620e..0000000 --- a/src/main/java/com/songoda/ultimatestacker/listeners/SpawnerListeners.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.songoda.ultimatestacker.listeners; - -import com.songoda.ultimatestacker.UltimateStacker; -import com.songoda.ultimatestacker.events.SpawnerBreakEvent; -import com.songoda.ultimatestacker.events.SpawnerPlaceEvent; -import com.songoda.ultimatestacker.spawner.SpawnerStack; -import com.songoda.ultimatestacker.utils.Methods; -import com.songoda.ultimatestacker.utils.ServerVersion; -import com.songoda.ultimatestacker.utils.settings.Setting; -import org.apache.commons.lang.math.NumberUtils; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.CreatureSpawner; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.entity.SpawnerSpawnEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BlockStateMeta; - -import java.util.List; -import java.util.Random; - -public class SpawnerListeners implements Listener { - - private final UltimateStacker instance; - - public SpawnerListeners(UltimateStacker instance) { - this.instance = instance; - } - - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onSpawnerSpawn(SpawnerSpawnEvent event) { - if (!instance.spawnersEnabled() || !(event.getEntity() instanceof LivingEntity)) return; - - if (instance.getStackingTask().attemptAddToStack((LivingEntity) event.getEntity(), null)) { - Entity entity = event.getEntity(); - if (entity.getVehicle() != null) { - entity.getVehicle().remove(); - entity.remove(); - } - - if (instance.isServerVersionAtLeast(ServerVersion.V1_11)) { - if (entity.getPassengers().size() != 0) { - for (Entity e : entity.getPassengers()) { - e.remove(); - } - entity.remove(); - } - } - entity.remove(); - - } - } -} diff --git a/src/main/java/com/songoda/ultimatestacker/lootables/Loot.java b/src/main/java/com/songoda/ultimatestacker/lootables/Loot.java new file mode 100644 index 0000000..90b0d0e --- /dev/null +++ b/src/main/java/com/songoda/ultimatestacker/lootables/Loot.java @@ -0,0 +1,169 @@ +package com.songoda.ultimatestacker.lootables; + +import com.google.gson.annotations.SerializedName; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +public class Loot { + + // Material used for this drop. + @SerializedName("Type") + private Material material; + + // Data value for old crappy versions of Minecraft. + @SerializedName("Data") + private Short data; + + // Material used if entity died on fire. + @SerializedName("Burned Type") + private Material burnedMaterial = null; + + // Chance that this drop will take place. + @SerializedName("Chance") + private double chance = 100; + + // Minimum amount of this item. + @SerializedName("Min") + private int min = 1; + + // Maximum amount of this item. + @SerializedName("Max") + private int max = 1; + + // Will the looting enchantment be usable for this loot? + @SerializedName("Looting") + private boolean allowLootingEnchant = true; + + // The looting chance increase. + @SerializedName("Looting Chance Increase") + private Double lootingIncrease; + + // Should this drop only be applicable for specific entities? + @SerializedName("Only Drop For") + private List onlyDropFor; + + // How many child loots should drop? + @SerializedName("Child Loot Drop Count Min") + private Integer childDropCountMin; + @SerializedName("Child Loot Drop Count Max") + private Integer childDropCountMax; + + // Should this drop house child drops? + @SerializedName("Child Loot") + private List childLoot; + + public Material getMaterial() { + return material; + } + + public void setMaterial(Material material) { + this.material = material; + } + + public Short getData() { + return data; + } + + public void setData(Short data) { + this.data = data; + } + + public Material getBurnedMaterial() { + return burnedMaterial; + } + + public void setBurnedMaterial(Material burnedMaterial) { + this.burnedMaterial = burnedMaterial; + } + + public double getChance() { + return chance; + } + + public void setChance(double chance) { + this.chance = chance; + } + + public boolean runChance(int looting) { + return (Math.random() * 100) - (chance + (lootingIncrease == null ? 1 + : lootingIncrease * looting)) < 0 || chance == 100; + } + + public int getMin() { + return min; + } + + public void setMin(int min) { + this.min = min; + } + + public int getMax() { + return max; + } + + public void setMax(int max) { + this.max = max; + } + + public int getAmountToDrop(int looting) { + return min == max ? (max + getLooting(looting)) : new Random().nextInt((max + getLooting(looting)) - min + 1) + min; + } + + public int getLooting(int looting) { + return allowLootingEnchant ? looting : 0; + } + + public boolean isAllowLootingEnchant() { + return allowLootingEnchant; + } + + public void setAllowLootingEnchant(boolean allowLootingEnchant) { + this.allowLootingEnchant = allowLootingEnchant; + } + + public void setLootingIncrease(double increase) { + this.lootingIncrease = increase; + } + + public List getChild() { + return childLoot == null ? new ArrayList<>() : new ArrayList<>(childLoot); + } + + public void addChildLoots(Loot... loots) { + this.childDropCountMin = 1; + this.childDropCountMax = 1; + this.childLoot = new ArrayList<>(); + this.childLoot.addAll(Arrays.asList(loots)); + } + + public List getChildLoot() { + return childLoot == null ? new ArrayList<>() : new ArrayList<>(childLoot); + } + + public List getOnlyDropFor() { + return onlyDropFor == null ? new ArrayList<>() : new ArrayList<>(onlyDropFor); + } + + public void addOnlyDropFors(EntityType... types) { + this.onlyDropFor = new ArrayList<>(); + this.onlyDropFor.addAll(Arrays.asList(types)); + } + + public void setChildDropCountMin(int childDropCountMin) { + this.childDropCountMin = childDropCountMin; + } + + public void setChildDropCountMax(int childDropCountMax) { + this.childDropCountMax = childDropCountMax; + } + + public int getChildDropCount() { + if (childDropCountMin == null || childDropCountMax == null) return 0; + return new Random().nextInt(childDropCountMax - childDropCountMax) + childDropCountMin; + } +} diff --git a/src/main/java/com/songoda/ultimatestacker/lootables/LootBuilder.java b/src/main/java/com/songoda/ultimatestacker/lootables/LootBuilder.java new file mode 100644 index 0000000..b483c3a --- /dev/null +++ b/src/main/java/com/songoda/ultimatestacker/lootables/LootBuilder.java @@ -0,0 +1,88 @@ +package com.songoda.ultimatestacker.lootables; + + +import org.bukkit.Material; +import org.bukkit.entity.EntityType; + +public final class LootBuilder { + + private final Loot loot; + + public LootBuilder() { + this.loot = new Loot(); + } + + public LootBuilder setMaterial(Material material) { + this.loot.setMaterial(material); + return this; + } + + public LootBuilder setData(int data) { + return setData((short)data); + } + + public LootBuilder setData(short data) { + this.loot.setData(data); + return this; + } + + public LootBuilder setBurnedMaterial(Material material) { + this.loot.setBurnedMaterial(material); + return this; + } + + public LootBuilder setChance(double chance) { + this.loot.setChance(chance); + return this; + } + + public LootBuilder setMin(int min) { + this.loot.setMin(min); + return this; + } + + public LootBuilder setMax(int max) { + this.loot.setMax(max); + return this; + } + + public LootBuilder setAllowLootingEnchant(boolean allow) { + this.loot.setAllowLootingEnchant(allow); + return this; + } + + public LootBuilder setLootingIncrease(double increase) { + this.loot.setLootingIncrease(increase); + return this; + } + + public LootBuilder addOnlyDropFors(EntityType... types) { + this.loot.addOnlyDropFors(types); + return this; + } + + public LootBuilder addChildLoot(Loot... loots) { + this.loot.addChildLoots(loots); + return this; + } + + public LootBuilder setChildDropCount(int count) { + this.loot.setChildDropCountMin(count); + this.loot.setChildDropCountMax(count); + return this; + } + + public LootBuilder setChildDropCounMin(int count) { + this.loot.setChildDropCountMin(count); + return this; + } + + public LootBuilder setChildDropCountMax(int count) { + this.loot.setChildDropCountMax(count); + return this; + } + + public Loot build() { + return this.loot; + } +} \ No newline at end of file diff --git a/src/main/java/com/songoda/ultimatestacker/lootables/LootManager.java b/src/main/java/com/songoda/ultimatestacker/lootables/LootManager.java new file mode 100644 index 0000000..47ec577 --- /dev/null +++ b/src/main/java/com/songoda/ultimatestacker/lootables/LootManager.java @@ -0,0 +1,839 @@ +package com.songoda.ultimatestacker.lootables; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.stream.JsonReader; +import com.songoda.ultimatestacker.UltimateStacker; +import com.songoda.ultimatestacker.utils.ServerVersion; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Ageable; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Sheep; +import org.bukkit.inventory.ItemStack; + +import java.io.*; +import java.util.*; + +public class LootManager { + + private final Map registeredLootables = new HashMap<>(); + + private final String lootablesDir = UltimateStacker.getInstance().getDataFolder() + "/lootables"; + + public Lootable addLootable(Lootable lootable) { + return registeredLootables.put(lootable.getType(), lootable); + } + + public List getDrops(LivingEntity entity) { + List toDrop = new ArrayList<>(); + if (entity instanceof Ageable && !((Ageable) entity).isAdult() + || !registeredLootables.containsKey(entity.getType())) return toDrop; + + Lootable lootable = registeredLootables.get(entity.getType()); + int looting = entity.getKiller() != null + && entity.getKiller().getItemInHand().containsEnchantment(Enchantment.LOOT_BONUS_MOBS) + ? entity.getKiller().getItemInHand().getEnchantmentLevel(Enchantment.LOOT_BONUS_MOBS) + : 0; + + int rerollChance = looting / (looting + 1); + + for (Loot loot : lootable.getRegisteredLoot()) + toDrop.addAll(runLoot(entity, loot, rerollChance, looting)); + + return toDrop; + } + + private List runLoot(LivingEntity entity, Loot loot, int rerollChance, int looting) { + List toDrop = new ArrayList<>(); + if (loot.runChance(looting) || ((Math.random() * 100) - rerollChance < 0 || rerollChance == 100) + && loot.runChance(looting)) { + + if (loot.getOnlyDropFor().size() != 0 + && entity.getKiller() != null + && loot.getOnlyDropFor().stream().noneMatch(type -> type == entity.getKiller().getType())) + return toDrop; + + if (loot.getChildLoot().size() > 0) { + List childLoot = loot.getChildLoot(); + Collections.shuffle(childLoot); + + int amt = loot.getChildDropCount(); + + for (int i = 0; i < amt; i++) { + toDrop.addAll(runLoot(entity, childLoot.get(i), rerollChance, looting)); + } + } + + if (loot.getMaterial() == null) return toDrop; + + Material material = loot.getMaterial(); + + short data = loot.getData() != null ? loot.getData() : 0; + + if (entity.getType() == EntityType.SHEEP + && material == (UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) + ? Material.WHITE_WOOL : Material.valueOf("WOOL")) + && ((Sheep) entity).getColor() != null) { + if (((Sheep) entity).isSheared()) return null; + if (UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13)) + material = Material.valueOf(((Sheep) entity).getColor() + "_WOOL"); + else + data = ((Sheep) entity).getColor().getWoolData(); + + } + + int amount = loot.getAmountToDrop(looting); + if (amount == 0) return toDrop; + + ItemStack item = new ItemStack(loot.getBurnedMaterial() != null && entity.getFireTicks() != -1 + ? loot.getBurnedMaterial() : material, amount); + item.setDurability(data); + toDrop.add(item); + } + return toDrop; + } + + public void loadLootables() { + File dir = new File(lootablesDir); + File[] directoryListing = dir.listFiles(); + if (directoryListing != null) { + for (File file : directoryListing) { + if (!file.getName().endsWith(".json")) continue; + try { + Gson gson = new Gson(); + JsonReader reader = new JsonReader(new FileReader(file.getPath())); + + Lootable lootable = gson.fromJson(reader, Lootable.class); + + if (lootable.getRegisteredLoot().size() != 0) + addLootable(lootable); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + } + } + + public void createDefaultLootables() { + UltimateStacker plugin = UltimateStacker.getInstance(); + + if (plugin.isServerVersionAtLeast(ServerVersion.V1_14)) { + // Add Trader Llama. + addLootable(new Lootable(EntityType.TRADER_LLAMA, + new LootBuilder() + .setMaterial(Material.LEATHER) + .setMin(0) + .setMax(2).build())); + + // Add Pillager. + addLootable(new Lootable(EntityType.PILLAGER, + new LootBuilder() + .setMaterial(Material.ARROW) + .setMin(0) + .setMax(2).build())); + + // Add Ravager. + addLootable(new Lootable(EntityType.RAVAGER, + new LootBuilder() + .setMaterial(Material.SADDLE).build())); + + // Add Cat. + addLootable(new Lootable(EntityType.CAT, + new LootBuilder() + .setMaterial(Material.STRING).build())); + + // Add Panda. + addLootable(new Lootable(EntityType.PANDA, + new LootBuilder() + .setMaterial(Material.BAMBOO) + .setMin(0) + .setMax(2).build())); + } + + if (plugin.isServerVersionAtLeast(ServerVersion.V1_13)) { + + + // Add Phantom. + addLootable(new Lootable(EntityType.PHANTOM, + new LootBuilder() + .setMaterial(Material.PHANTOM_MEMBRANE) + .setMin(0) + .setMax(1) + .addOnlyDropFors(EntityType.PLAYER).build())); + + // Add Pufferfish. + addLootable(new Lootable(EntityType.PUFFERFISH, + new LootBuilder() + .setMaterial(Material.PUFFERFISH).build(), + new LootBuilder() + .setMaterial(Material.BONE_MEAL) + .setChance(5).build())); + + // Add Salmon. + addLootable(new Lootable(EntityType.SALMON, + new LootBuilder() + .setMaterial(Material.SALMON) + .setBurnedMaterial(Material.COOKED_SALMON).build(), + new LootBuilder() + .setMaterial(Material.BONE_MEAL) + .setChance(5).build())); + + // Add Tropical Fish. + addLootable(new Lootable(EntityType.TROPICAL_FISH, + new LootBuilder() + .setMaterial(Material.TROPICAL_FISH).build(), + new LootBuilder() + .setMaterial(Material.BONE_MEAL) + .setChance(5).build(), + new LootBuilder() + .setMaterial(Material.RABBIT_FOOT) + .setChance(10) + .addOnlyDropFors(EntityType.PLAYER).build())); + + // Add Dolphin. + addLootable(new Lootable(EntityType.DOLPHIN, + new LootBuilder() + .setMaterial(Material.COD) + .setBurnedMaterial(Material.COOKED_COD) + .setMin(0) + .setMax(1).build())); + + // Add Cod. + addLootable(new Lootable(EntityType.COD, + new LootBuilder() + .setMaterial(Material.COD) + .setBurnedMaterial(Material.COOKED_COD).build(), + new LootBuilder() + .setMaterial(Material.BONE_MEAL) + .setChance(5).build())); + + // Add Turtle. + addLootable(new Lootable(EntityType.TURTLE, + new LootBuilder() + .setMaterial(Material.SEAGRASS) + .setMin(0) + .setMax(2).build())); + + // Add Drowned. + addLootable(new Lootable(EntityType.DROWNED, + new LootBuilder() + .setMaterial(Material.ROTTEN_FLESH) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(Material.GOLD_INGOT) + .setChance(5) + .addOnlyDropFors(EntityType.PLAYER).build())); + } + + + Loot fish1 = plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? new LootBuilder() + .addChildLoot(new LootBuilder() + .setMaterial(Material.COD) + .setBurnedMaterial(Material.COOKED_COD) + .setChance(50).build(), + new LootBuilder() + .setMaterial(Material.PRISMARINE_CRYSTALS) + .setChance(33).build()) + .build() + : + new LootBuilder() + .addChildLoot(new LootBuilder() + .setMaterial(Material.valueOf("RAW_FISH")) + .setBurnedMaterial(Material.valueOf("COOKED_FISH")) + .setChance(50).build(), + new LootBuilder() + .setMaterial(Material.PRISMARINE_CRYSTALS) + .setChance(33).build()) + .build(); + + Loot fish2 = plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? new LootBuilder() + .setChance(2.5) + .addChildLoot(new LootBuilder() + .setMaterial(Material.COD) + .setChance(60) + .setAllowLootingEnchant(false).build(), + new LootBuilder() + .setMaterial(Material.SALMON) + .setChance(25) + .setAllowLootingEnchant(false).build(), + new LootBuilder() + .setMaterial(Material.PUFFERFISH) + .setChance(13) + .setAllowLootingEnchant(false).build(), + new LootBuilder() + .setMaterial(Material.TROPICAL_FISH) + .setChance(2) + .setAllowLootingEnchant(false).build()) + .addOnlyDropFors(EntityType.PLAYER).build() + : + new LootBuilder() + .setChance(2.5) + .addChildLoot(new LootBuilder() + .setMaterial(Material.valueOf("RAW_FISH")) + .setChance(60) + .setAllowLootingEnchant(false).build(), + new LootBuilder() + .setMaterial(Material.valueOf("RAW_FISH")) + .setData(1) + .setChance(25) + .setAllowLootingEnchant(false).build(), + new LootBuilder() + .setMaterial(Material.valueOf("RAW_FISH")) + .setData(3) + .setChance(13) + .setAllowLootingEnchant(false).build(), + new LootBuilder() + .setMaterial(Material.valueOf("RAW_FISH")) + .setData(2) + .setChance(2) + .setAllowLootingEnchant(false).build()) + .addOnlyDropFors(EntityType.PLAYER).build(); + + if (plugin.isServerVersionAtLeast(ServerVersion.V1_11)) { + // Add Zombie Villager. + addLootable(new Lootable(EntityType.ZOMBIE_VILLAGER, + new LootBuilder() + .setMaterial(Material.ROTTEN_FLESH) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setChance(2.5) + .setChildDropCount(1) + .addOnlyDropFors(EntityType.PLAYER) + .addChildLoot(new LootBuilder().setMaterial(Material.IRON_INGOT) + .setAllowLootingEnchant(false).build(), + new LootBuilder().setMaterial(Material.CARROT) + .setAllowLootingEnchant(false).build(), + new LootBuilder().setMaterial(Material.POTATO) + .setAllowLootingEnchant(false).build()) + .build())); + + // Add Zombie Horse. + addLootable(new Lootable(EntityType.ZOMBIE_HORSE, + new LootBuilder() + .setMaterial(Material.ROTTEN_FLESH) + .setMin(0) + .setMax(2).build())); + // Add Elder Guardian. + addLootable(new Lootable(EntityType.ELDER_GUARDIAN, + new LootBuilder() + .setMaterial(Material.PRISMARINE_SHARD) + .setMin(0) + .setMax(2).build(), + fish1, + new LootBuilder() + .setMaterial(Material.SPONGE) + .addOnlyDropFors(EntityType.PLAYER) + .setAllowLootingEnchant(false).build(), + fish2)); + + // Add Mule. + addLootable(new Lootable(EntityType.MULE, + new LootBuilder() + .setMaterial(Material.LEATHER) + .setMin(0) + .setMax(2).build())); + + // Add Stray. + addLootable(new Lootable(EntityType.STRAY, + new LootBuilder() + .setMaterial(Material.ARROW) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(Material.BONE) + .setMin(0) + .setMax(2).build())); + + Loot witherSkull = plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? + new LootBuilder() + .setMaterial(Material.WITHER_SKELETON_SKULL) + .setChance(2.5) + .addOnlyDropFors(EntityType.PLAYER).build() + : + new LootBuilder() + .setMaterial(Material.valueOf("SKULL_ITEM")) + .setData(1) + .setChance(2.5) + .addOnlyDropFors(EntityType.PLAYER).build(); + + // Add Wither Skeleton. + addLootable(new Lootable(EntityType.WITHER_SKELETON, + new LootBuilder() + .setMaterial(Material.COAL) + .setChance(33).build(), + new LootBuilder() + .setMaterial(Material.BONE) + .setMin(0) + .setMax(2).build(), + witherSkull)); // Add Skeleton Horse. + addLootable(new Lootable(EntityType.SKELETON_HORSE, + new LootBuilder() + .setMaterial(Material.BONE) + .setMin(0) + .setMax(2).build())); + + // Add Donkey. + addLootable(new Lootable(EntityType.DONKEY, + new LootBuilder() + .setMaterial(Material.LEATHER) + .setMin(0) + .setMax(2).build())); + + // Add Vindicator. + addLootable(new Lootable(EntityType.VINDICATOR, + new LootBuilder() + .setMaterial(Material.EMERALD) + .setMin(0) + .setMax(1) + .addOnlyDropFors(EntityType.PLAYER).build())); + + // Add Evoker. + addLootable(new Lootable(EntityType.EVOKER, + new LootBuilder() + .setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13) + ? Material.TOTEM_OF_UNDYING : Material.valueOf("TOTEM")) + .setAllowLootingEnchant(false).build(), + new LootBuilder() + .setMaterial(Material.EMERALD) + .setChance(50) + .addOnlyDropFors(EntityType.PLAYER).build())); + } + + if (plugin.isServerVersionAtLeast(ServerVersion.V1_11)) { + + + // Shulker. + addLootable(new Lootable(EntityType.SHULKER, + new LootBuilder() + .setMaterial(Material.SHULKER_SHELL) + .setChance(50) + .setLootingIncrease(6.25).build())); + } + + if (plugin.isServerVersionAtLeast(ServerVersion.V1_13)) { + // Add Polar Bear. + addLootable(new Lootable(EntityType.POLAR_BEAR, + new LootBuilder() + .setMaterial(Material.COD) + .setChance(75) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(Material.SALMON) + .setChance(25) + .setMin(0) + .setMax(2).build())); + } else if (plugin.isServerVersionAtLeast(ServerVersion.V1_10)) { + // Add Polar Bear. + addLootable(new Lootable(EntityType.POLAR_BEAR, + new LootBuilder() + .setMaterial(Material.valueOf("RAW_FISH")) + .setChance(75) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(Material.valueOf("RAW_FISH")) + .setData(1) + .setChance(25) + .setMin(0) + .setMax(2).build())); + } + + // Add Pig. + addLootable(new Lootable(EntityType.PIG, + new LootBuilder() + .setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13) + ? Material.PORKCHOP : Material.valueOf("PORK")) + .setBurnedMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13) + ? Material.COOKED_PORKCHOP : Material.valueOf("GRILLED_PORK")) + .setMin(1) + .setMax(3).build())); + + + // Add Cow. + addLootable(new Lootable(EntityType.COW, + new LootBuilder() + .setMaterial(Material.LEATHER) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13) + ? Material.BEEF : Material.valueOf("RAW_BEEF")) + .setBurnedMaterial(Material.COOKED_BEEF) + .setMin(1) + .setMax(3).build())); + + // Add Mushroom Cow. + addLootable(new Lootable(EntityType.MUSHROOM_COW, + new LootBuilder() + .setMaterial(Material.LEATHER) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13) + ? Material.BEEF : Material.valueOf("RAW_BEEF")) + .setBurnedMaterial(Material.COOKED_BEEF) + .setMin(1) + .setMax(3).build())); + + // Add Chicken. + addLootable(new Lootable(EntityType.CHICKEN, + new LootBuilder() + .setMaterial(Material.FEATHER) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13) + ? Material.CHICKEN : Material.valueOf("RAW_CHICKEN")) + .setBurnedMaterial(Material.COOKED_CHICKEN).build())); + // Add Zombie. + addLootable(new Lootable(EntityType.ZOMBIE, + new LootBuilder() + .setMaterial(Material.ROTTEN_FLESH) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setChance(2.5) + .setChildDropCount(1) + .setAllowLootingEnchant(false) + .addOnlyDropFors(EntityType.PLAYER) + .addChildLoot(new LootBuilder().setMaterial(Material.IRON_INGOT) + .setAllowLootingEnchant(false).build(), + new LootBuilder().setMaterial(Material.CARROT) + .setAllowLootingEnchant(false).build(), + new LootBuilder().setMaterial(Material.POTATO) + .setAllowLootingEnchant(false).build()) + .build())); + + // Add Husk. + addLootable(new Lootable(EntityType.ZOMBIE, + new LootBuilder() + .setMaterial(Material.ROTTEN_FLESH) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setChance(2.5) + .setChildDropCount(1) + .setAllowLootingEnchant(false) + .addOnlyDropFors(EntityType.PLAYER) + .addChildLoot(new LootBuilder().setMaterial(Material.IRON_INGOT) + .setAllowLootingEnchant(false).build(), + new LootBuilder().setMaterial(Material.CARROT) + .setAllowLootingEnchant(false).build(), + new LootBuilder().setMaterial(Material.POTATO) + .setAllowLootingEnchant(false).build()) + .build())); + + Loot discs; + if (plugin.isServerVersionAtLeast(ServerVersion.V1_13)) { + discs = new LootBuilder() + .setChildDropCount(1) + .addOnlyDropFors(EntityType.SKELETON, + EntityType.STRAY) + .addChildLoot(new LootBuilder().setMaterial(Material.MUSIC_DISC_11).build(), + new LootBuilder().setMaterial(Material.MUSIC_DISC_13).build(), + new LootBuilder().setMaterial(Material.MUSIC_DISC_BLOCKS).build(), + new LootBuilder().setMaterial(Material.MUSIC_DISC_CAT).build(), + new LootBuilder().setMaterial(Material.MUSIC_DISC_CHIRP).build(), + new LootBuilder().setMaterial(Material.MUSIC_DISC_FAR).build(), + new LootBuilder().setMaterial(Material.MUSIC_DISC_MALL).build(), + new LootBuilder().setMaterial(Material.MUSIC_DISC_MELLOHI).build(), + new LootBuilder().setMaterial(Material.MUSIC_DISC_STAL).build(), + new LootBuilder().setMaterial(Material.MUSIC_DISC_STRAD).build(), + new LootBuilder().setMaterial(Material.MUSIC_DISC_WAIT).build(), + new LootBuilder().setMaterial(Material.MUSIC_DISC_WARD).build()) + .build(); + } else if (plugin.isServerVersionAtLeast(ServerVersion.V1_11)) { + discs = new LootBuilder() + .setChildDropCount(1) + .addOnlyDropFors(EntityType.SKELETON, + EntityType.STRAY) + .addChildLoot(new LootBuilder().setMaterial(Material.valueOf("GOLD_RECORD")).build(), + new LootBuilder().setMaterial(Material.valueOf("GREEN_RECORD")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_3")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_4")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_5")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_6")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_7")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_8")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_9")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_10")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_11")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_12")).build()) + .build(); + } else { + discs = new LootBuilder() + .setChildDropCount(1) + .addOnlyDropFors(EntityType.SKELETON) + .addChildLoot(new LootBuilder().setMaterial(Material.valueOf("GOLD_RECORD")).build(), + new LootBuilder().setMaterial(Material.valueOf("GREEN_RECORD")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_3")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_4")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_5")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_6")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_7")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_8")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_9")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_10")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_11")).build(), + new LootBuilder().setMaterial(Material.valueOf("RECORD_12")).build()) + .build(); + } + + // Add Creeper. + addLootable(new Lootable(EntityType.CREEPER, + new LootBuilder() + .setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13) + ? Material.GUNPOWDER : Material.valueOf("SULPHUR")) + .setMin(0) + .setMax(2).build(), + discs)); + + // Add Guardian. + addLootable(new Lootable(EntityType.GUARDIAN, + new LootBuilder() + .setMaterial(Material.PRISMARINE_SHARD) + .setMin(0) + .setMax(2).build(), + fish1, + fish2)); + + // Add Witch. + addLootable(new Lootable(EntityType.WITCH, + new LootBuilder() + .setChildDropCounMin(1) + .setChildDropCountMax(3) + .addChildLoot(new LootBuilder() + .setMaterial(Material.GLOWSTONE_DUST) + .setChance(12.5) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(Material.SUGAR) + .setChance(12.5) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(Material.REDSTONE) + .setChance(12.5) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(Material.SPIDER_EYE) + .setChance(12.5) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(Material.GLASS_BOTTLE) + .setChance(12.5) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13) + ? Material.GUNPOWDER : Material.valueOf("SULPHUR")) + .setChance(12.5) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(Material.STICK) + .setChance(25) + .setMin(0) + .setMax(2).build() + ).build())); + + // Add Sheep. + addLootable(new Lootable(EntityType.SHEEP, + new LootBuilder() + .setMaterial(Material.MUTTON) + .setBurnedMaterial(Material.COOKED_MUTTON) + .setMin(1) + .setMax(2).build(), + new LootBuilder() + .setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13) + ? Material.WHITE_WOOL : Material.valueOf("WOOL")) + .setMin(2) + .setMax(2).build())); + + // Add Squid. + addLootable(new Lootable(EntityType.SQUID, + new LootBuilder() + .setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13) + ? Material.INK_SAC : Material.valueOf("INK_SACK")) + .setMin(1) + .setMax(3).build())); + + // Add Spider. + addLootable(new Lootable(EntityType.SPIDER, + new LootBuilder() + .setMaterial(Material.STRING) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(Material.SPIDER_EYE) + .setChance(33) + .addOnlyDropFors(EntityType.PLAYER).build())); + + // Add Cave Spider. + addLootable(new Lootable(EntityType.CAVE_SPIDER, + new LootBuilder() + .setMaterial(Material.STRING) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(Material.SPIDER_EYE) + .setChance(33) + .addOnlyDropFors(EntityType.PLAYER).build())); + + // Add Enderman. + addLootable(new Lootable(EntityType.ENDERMAN, + new LootBuilder() + .setMaterial(Material.ENDER_PEARL) + .setMin(0) + .setMax(1).build())); + + // Add Blaze. + addLootable(new Lootable(EntityType.BLAZE, + new LootBuilder() + .setMaterial(Material.BLAZE_ROD) + .setMin(0) + .setMax(1) + .addOnlyDropFors(EntityType.PLAYER).build())); + + // Add Horse. + addLootable(new Lootable(EntityType.HORSE, + new LootBuilder() + .setMaterial(Material.LEATHER) + .setMin(0) + .setMax(2).build())); + + // Magma Cube. + addLootable(new Lootable(EntityType.MAGMA_CUBE, + new LootBuilder() + .setMaterial(Material.MAGMA_CREAM) + .setChance(25).build())); + // Add Skeleton. + addLootable(new Lootable(EntityType.SKELETON, + new LootBuilder() + .setMaterial(Material.ARROW) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(Material.BONE) + .setMin(0) + .setMax(2).build())); + + // Add Snowman. + addLootable(new Lootable(EntityType.SNOWMAN, + new LootBuilder() + .setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13) + ? Material.SNOWBALL : Material.valueOf("SNOW_BALL")) + .setMin(0) + .setMax(15).build())); + + // Add Rabbit. + addLootable(new Lootable(EntityType.RABBIT, + new LootBuilder() + .setMaterial(Material.RABBIT_HIDE) + .setMin(0) + .setMax(1).build(), + new LootBuilder() + .setMaterial(Material.RABBIT) + .setBurnedMaterial(Material.COOKED_RABBIT) + .setMin(0) + .setMax(1).build())); + + // Add Iron Golem. + addLootable(new Lootable(EntityType.IRON_GOLEM, + new LootBuilder() + .setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13) + ? Material.POPPY : Material.valueOf("RED_ROSE")) + .setMin(0) + .setMax(2).build(), + new LootBuilder() + .setMaterial(Material.IRON_INGOT) + .setMin(3) + .setMax(5).build())); + + // Add Slime. + addLootable(new Lootable(EntityType.SLIME, + new LootBuilder() + .setMaterial(Material.SLIME_BALL) + .setMin(0) + .setMax(2).build())); + + // Add Ghast. + addLootable(new Lootable(EntityType.GHAST, + new LootBuilder() + .setMaterial(Material.GHAST_TEAR) + .setMin(0) + .setMax(1).build(), + new LootBuilder() + .setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13) + ? Material.GUNPOWDER : Material.valueOf("SULPHUR")) + .setMin(0) + .setMax(2) + .setBurnedMaterial(Material.COOKED_CHICKEN).build())); + + // Add Zombie Pigman + addLootable(new Lootable(EntityType.PIG_ZOMBIE, + new LootBuilder() + .setMaterial(Material.ROTTEN_FLESH) + .setMin(0) + .setMax(1).build(), + new LootBuilder() + .setMaterial(Material.GOLD_NUGGET) + .setMin(0) + .setMax(1).build(), + new LootBuilder() + .setMaterial(Material.GOLD_INGOT) + .setChance(2.5) + .addOnlyDropFors(EntityType.PLAYER).build())); + + // Add Parrot. + addLootable(new Lootable(EntityType.CHICKEN, + new LootBuilder() + .setMaterial(Material.FEATHER) + .setMin(1) + .setMax(2).build())); + + // Add Wither. + addLootable(new Lootable(EntityType.WITHER, + new LootBuilder() + .setMaterial(Material.NETHER_STAR) + .setAllowLootingEnchant(false).build())); + + + for (EntityType value : EntityType.values()) { + if (value.isSpawnable() && value.isAlive() && !value.toString().contains("ARMOR")) { + if (registeredLootables.containsKey(value)) continue; + addLootable(new Lootable(value)); + } + } + + // Save to file + for (Lootable lootable : registeredLootables.values()) { + try { + File dir = new File(lootablesDir); + dir.mkdir(); + + File file = new File(lootablesDir + "/" + lootable.getType().name().toLowerCase() + ".json"); + if (file.exists()) continue; + + try (Writer writer = new FileWriter(file.getPath())) { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + gson.toJson(lootable, writer); + } + + } catch (IOException e) { + e.printStackTrace(); + } + } + + registeredLootables.clear(); + } +} diff --git a/src/main/java/com/songoda/ultimatestacker/lootables/Lootable.java b/src/main/java/com/songoda/ultimatestacker/lootables/Lootable.java new file mode 100644 index 0000000..5fbcb3e --- /dev/null +++ b/src/main/java/com/songoda/ultimatestacker/lootables/Lootable.java @@ -0,0 +1,32 @@ +package com.songoda.ultimatestacker.lootables; + +import com.google.gson.annotations.SerializedName; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Lootable { + + // The entity applicable to this lootable. + @SerializedName("Type") + private final EntityType type; + + // Registered loot. + @SerializedName("Loot") + private final List registeredLoot = new ArrayList<>(); + + public Lootable(EntityType type, Loot... loots) { + this.type = type; + registeredLoot.addAll(Arrays.asList(loots)); + } + + public List getRegisteredLoot() { + return new ArrayList<>(registeredLoot); + } + + public EntityType getType() { + return type; + } +} diff --git a/src/main/java/com/songoda/ultimatestacker/utils/settings/Setting.java b/src/main/java/com/songoda/ultimatestacker/utils/settings/Setting.java index 3d62f2a..8bf945d 100644 --- a/src/main/java/com/songoda/ultimatestacker/utils/settings/Setting.java +++ b/src/main/java/com/songoda/ultimatestacker/utils/settings/Setting.java @@ -39,6 +39,9 @@ public enum Setting { HOLOGRAMS_ON_LOOK_ENTITY("Entities.Only Show Holograms On Look", false, "Only show nametags above an entities head when looking directly at them."), + CUSTOM_DROPS("Entities.Custom Drops", true, + "Should custom drops be enabled?"), + KILL_WHOLE_STACK_ON_DEATH("Entities.Kill Whole Stack On Death", false, "Should killing a stack of entities kill the whole stack or", "just one out of the stack?"), @@ -135,7 +138,7 @@ public enum Setting { NAME_FORMAT_ITEM("Items.Name Format", "&f{TYPE} [&6{AMT}x]", "The text displayed above a dropped item."), - SHOW_STACK_SIZE_SINGLE("Items.Show Stack Size For Single,", false, + SHOW_STACK_SIZE_SINGLE("Items.Show Stack Size For Single", false, "When enabled stack sizes for a stack with a single item will", "not display the stack size. The stack size will be added", "for stacks containing two or more items."),