mirror of
https://github.com/songoda/SongodaCore.git
synced 2024-11-27 12:35:12 +01:00
Added Lootables to SongodaCore.
This commit is contained in:
parent
7430fcc34a
commit
c861aafe82
@ -13,6 +13,7 @@ public enum ClassMapping {
|
|||||||
BLOCK_POSITION("core", "BlockPosition"),
|
BLOCK_POSITION("core", "BlockPosition"),
|
||||||
CHAT_MESSAGE_TYPE("network.chat", "ChatMessageType"),
|
CHAT_MESSAGE_TYPE("network.chat", "ChatMessageType"),
|
||||||
CHUNK("world.level.chunk", "Chunk"),
|
CHUNK("world.level.chunk", "Chunk"),
|
||||||
|
ENCHANTMENT_MANAGER("world.item.enchantment", "EnchantmentManager"),
|
||||||
ENTITY("world.entity", "Entity"),
|
ENTITY("world.entity", "Entity"),
|
||||||
ENTITY_INSENTIENT("world.entity", "EntityInsentient"),
|
ENTITY_INSENTIENT("world.entity", "EntityInsentient"),
|
||||||
ENTITY_PLAYER("server.level", "EntityPlayer"),
|
ENTITY_PLAYER("server.level", "EntityPlayer"),
|
||||||
@ -40,6 +41,7 @@ public enum ClassMapping {
|
|||||||
CRAFT_BLOCK_DATA("block.data", "CraftBlockData"),
|
CRAFT_BLOCK_DATA("block.data", "CraftBlockData"),
|
||||||
CRAFT_CHUNK("CraftChunk"),
|
CRAFT_CHUNK("CraftChunk"),
|
||||||
CRAFT_ENTITY("entity", "CraftEntity"),
|
CRAFT_ENTITY("entity", "CraftEntity"),
|
||||||
|
CRAFT_ITEM_STACK("inventory", "CraftItemStack"),
|
||||||
CRAFT_PLAYER("entity", "CraftPlayer"),
|
CRAFT_PLAYER("entity", "CraftPlayer"),
|
||||||
CRAFT_WORLD("CraftWorld");
|
CRAFT_WORLD("CraftWorld");
|
||||||
|
|
||||||
|
23
Core/src/main/java/com/songoda/core/lootables/Lootables.java
Normal file
23
Core/src/main/java/com/songoda/core/lootables/Lootables.java
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package com.songoda.core.lootables;
|
||||||
|
|
||||||
|
import com.songoda.core.lootables.loot.LootManager;
|
||||||
|
|
||||||
|
public class Lootables {
|
||||||
|
|
||||||
|
private final String lootablesDir;
|
||||||
|
|
||||||
|
private final LootManager lootManager;
|
||||||
|
|
||||||
|
public Lootables(String lootablesDir) {
|
||||||
|
this.lootablesDir = lootablesDir;
|
||||||
|
this.lootManager = new LootManager(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLootablesDir() {
|
||||||
|
return lootablesDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LootManager getLootManager() {
|
||||||
|
return lootManager;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.songoda.core.lootables;
|
||||||
|
|
||||||
|
import com.songoda.core.lootables.loot.Loot;
|
||||||
|
|
||||||
|
public interface Modify {
|
||||||
|
|
||||||
|
Loot Modify(Loot loot);
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package com.songoda.core.lootables.gui;
|
||||||
|
|
||||||
|
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||||
|
import com.songoda.core.gui.AnvilGui;
|
||||||
|
import com.songoda.core.gui.Gui;
|
||||||
|
import com.songoda.core.gui.GuiUtils;
|
||||||
|
import com.songoda.core.utils.TextUtils;
|
||||||
|
import com.songoda.core.lootables.loot.Loot;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public abstract class AbstractGuiListEditor extends Gui {
|
||||||
|
|
||||||
|
protected final Loot loot;
|
||||||
|
private final Gui returnGui;
|
||||||
|
|
||||||
|
public AbstractGuiListEditor(Loot loot ,Gui returnGui) {
|
||||||
|
super(1, returnGui);
|
||||||
|
this.returnGui = returnGui;
|
||||||
|
this.loot = loot;
|
||||||
|
setDefaultItem(null);
|
||||||
|
paint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint() {
|
||||||
|
List<String> lore = getData() == null ? new ArrayList<>() : getData();
|
||||||
|
setButton(2, GuiUtils.createButtonItem(CompatibleMaterial.OAK_FENCE_GATE,
|
||||||
|
TextUtils.formatText("&cBack")),
|
||||||
|
(event) -> {
|
||||||
|
guiManager.showGUI(event.player, returnGui);
|
||||||
|
((GuiLootEditor) returnGui).paint();
|
||||||
|
});
|
||||||
|
setButton(6, GuiUtils.createButtonItem(CompatibleMaterial.OAK_FENCE_GATE,
|
||||||
|
TextUtils.formatText("&cBack")),
|
||||||
|
(event) -> {
|
||||||
|
guiManager.showGUI(event.player, returnGui);
|
||||||
|
((GuiLootEditor) returnGui).paint();
|
||||||
|
});
|
||||||
|
setButton(3, GuiUtils.createButtonItem(CompatibleMaterial.ARROW,
|
||||||
|
TextUtils.formatText("&aAdd new line")),
|
||||||
|
(event -> {
|
||||||
|
AnvilGui gui = new AnvilGui(event.player, this);
|
||||||
|
gui.setAction((e -> {
|
||||||
|
String validated = validate(gui.getInputText());
|
||||||
|
if (validated != null) {
|
||||||
|
lore.add(validated);
|
||||||
|
updateData(lore.isEmpty() ? null : lore);
|
||||||
|
e.player.closeInventory();
|
||||||
|
paint();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
gui.setTitle("Enter a new line");
|
||||||
|
guiManager.showGUI(event.player, gui);
|
||||||
|
}));
|
||||||
|
|
||||||
|
setItem(4, GuiUtils.createButtonItem(CompatibleMaterial.WRITABLE_BOOK,
|
||||||
|
TextUtils.formatText("&9Lore:"),
|
||||||
|
lore.isEmpty()
|
||||||
|
? TextUtils.formatText(Collections.singletonList("&cNo lore set..."))
|
||||||
|
: TextUtils.formatText(lore)));
|
||||||
|
|
||||||
|
setButton(5, GuiUtils.createButtonItem(CompatibleMaterial.ARROW,
|
||||||
|
TextUtils.formatText("&cRemove the last line")),
|
||||||
|
(event -> {
|
||||||
|
lore.remove(lore.size() - 1);
|
||||||
|
updateData(lore);
|
||||||
|
paint();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract List<String> getData();
|
||||||
|
|
||||||
|
protected abstract void updateData(List<String> list);
|
||||||
|
|
||||||
|
protected abstract String validate(String line);
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
package com.songoda.core.lootables.gui;
|
||||||
|
|
||||||
|
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||||
|
import com.songoda.core.gui.Gui;
|
||||||
|
import com.songoda.core.gui.GuiUtils;
|
||||||
|
import com.songoda.core.lootables.loot.LootManager;
|
||||||
|
import com.songoda.core.lootables.loot.Lootable;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GuiEditor extends Gui {
|
||||||
|
|
||||||
|
private final LootManager lootManager;
|
||||||
|
|
||||||
|
public GuiEditor(LootManager lootManager) {
|
||||||
|
super(6);
|
||||||
|
this.lootManager = lootManager;
|
||||||
|
setDefaultItem(null);
|
||||||
|
setTitle("Lootables Overview");
|
||||||
|
|
||||||
|
paint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void paint() {
|
||||||
|
if (inventory != null)
|
||||||
|
inventory.clear();
|
||||||
|
setActionForRange(0, 0, 5, 9, null);
|
||||||
|
|
||||||
|
List<Lootable> lootables = new ArrayList<>(lootManager.getRegisteredLootables().values());
|
||||||
|
|
||||||
|
double itemCount = lootables.size();
|
||||||
|
this.pages = (int) Math.max(1, Math.ceil(itemCount / 36));
|
||||||
|
|
||||||
|
if (page != 1)
|
||||||
|
setButton(5, 2, GuiUtils.createButtonItem(CompatibleMaterial.ARROW, "Back"),
|
||||||
|
(event) -> {
|
||||||
|
page--;
|
||||||
|
paint();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (page != pages)
|
||||||
|
setButton(5, 6, GuiUtils.createButtonItem(CompatibleMaterial.ARROW, "Next"),
|
||||||
|
(event) -> {
|
||||||
|
page++;
|
||||||
|
paint();
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int i = 9; i < 45; i++) {
|
||||||
|
int current = ((page - 1) * 36) - 9;
|
||||||
|
if (current + i >= lootables.size()) {
|
||||||
|
setItem(i, null);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Lootable lootable = lootables.get(current + i);
|
||||||
|
if (lootable == null) continue;
|
||||||
|
|
||||||
|
setButton(i, getIcon(lootable.getKey()),
|
||||||
|
(event) -> guiManager.showGUI(event.player, new GuiLootableEditor(lootManager, lootable, this)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack getIcon(String key) {
|
||||||
|
ItemStack stack = null;
|
||||||
|
EntityType type = EntityType.fromName(key);
|
||||||
|
if (type != null) {
|
||||||
|
CompatibleMaterial material = CompatibleMaterial.getSpawnEgg(type);
|
||||||
|
if (material != null)
|
||||||
|
stack = material.getItem();
|
||||||
|
}
|
||||||
|
if (stack == null)
|
||||||
|
stack = CompatibleMaterial.GHAST_SPAWN_EGG.getItem();
|
||||||
|
ItemMeta meta = stack.getItemMeta();
|
||||||
|
meta.setDisplayName(key);
|
||||||
|
stack.setItemMeta(meta);
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
package com.songoda.core.lootables.gui;
|
||||||
|
|
||||||
|
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||||
|
import com.songoda.core.gui.AnvilGui;
|
||||||
|
import com.songoda.core.gui.Gui;
|
||||||
|
import com.songoda.core.gui.GuiUtils;
|
||||||
|
import com.songoda.core.lootables.loot.Loot;
|
||||||
|
import com.songoda.core.utils.TextUtils;
|
||||||
|
import com.songoda.core.lootables.loot.Loot;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class GuiEnchantEditor extends Gui {
|
||||||
|
|
||||||
|
private final Gui returnGui;
|
||||||
|
private final Loot loot;
|
||||||
|
|
||||||
|
public GuiEnchantEditor(Loot loot, Gui returnGui) {
|
||||||
|
super(1, returnGui);
|
||||||
|
this.returnGui = returnGui;
|
||||||
|
this.loot = loot;
|
||||||
|
setDefaultItem(null);
|
||||||
|
setTitle("Enchantment Editor");
|
||||||
|
paint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint() {
|
||||||
|
Map<String, Integer> lore = loot.getEnchants() == null ? new HashMap<>() : new HashMap<>(loot.getEnchants());
|
||||||
|
setButton(2, GuiUtils.createButtonItem(CompatibleMaterial.OAK_FENCE_GATE,
|
||||||
|
TextUtils.formatText("&cBack")),
|
||||||
|
(event) -> {
|
||||||
|
guiManager.showGUI(event.player, returnGui);
|
||||||
|
((GuiLootEditor) returnGui).paint();
|
||||||
|
});
|
||||||
|
setButton(6, GuiUtils.createButtonItem(CompatibleMaterial.OAK_FENCE_GATE,
|
||||||
|
TextUtils.formatText("&cBack")),
|
||||||
|
(event) -> {
|
||||||
|
guiManager.showGUI(event.player, returnGui);
|
||||||
|
((GuiLootEditor) returnGui).paint();
|
||||||
|
});
|
||||||
|
setButton(3, GuiUtils.createButtonItem(CompatibleMaterial.ARROW,
|
||||||
|
TextUtils.formatText("&aAdd new line")),
|
||||||
|
(event -> {
|
||||||
|
AnvilGui gui = new AnvilGui(event.player, this);
|
||||||
|
gui.setAction((e -> {
|
||||||
|
if (Enchantment.getByName(gui.getInputText().toUpperCase().trim()) == null) {
|
||||||
|
e.player.sendMessage("That is not a valid enchantment.");
|
||||||
|
e.player.closeInventory();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AnvilGui gui1 = new AnvilGui(event.player, this);
|
||||||
|
gui1.setAction((ee -> {
|
||||||
|
lore.put(gui.getInputText().toUpperCase().trim(), Integer.parseInt(gui1.getInputText().trim()));
|
||||||
|
loot.setEnchants(lore.isEmpty() ? null : lore);
|
||||||
|
ee.player.closeInventory();
|
||||||
|
paint();
|
||||||
|
}));
|
||||||
|
gui1.setTitle("Enter a level");
|
||||||
|
guiManager.showGUI(event.player, gui1);
|
||||||
|
}));
|
||||||
|
gui.setTitle("Enter an enchant");
|
||||||
|
guiManager.showGUI(event.player, gui);
|
||||||
|
}));
|
||||||
|
|
||||||
|
List<String> enchantments = new ArrayList<>();
|
||||||
|
|
||||||
|
String last = null;
|
||||||
|
|
||||||
|
if (!lore.isEmpty())
|
||||||
|
for (Map.Entry<String, Integer> entry : lore.entrySet()) {
|
||||||
|
last = entry.getKey();
|
||||||
|
enchantments.add("&6" + entry.getKey() + " " + entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
setItem(4, GuiUtils.createButtonItem(CompatibleMaterial.WRITABLE_BOOK,
|
||||||
|
TextUtils.formatText("&7Enchant Override:"),
|
||||||
|
lore.isEmpty()
|
||||||
|
? TextUtils.formatText(Collections.singletonList("&cNo enchantments set..."))
|
||||||
|
: TextUtils.formatText(enchantments)));
|
||||||
|
|
||||||
|
String lastFinal = last;
|
||||||
|
setButton(5, GuiUtils.createButtonItem(CompatibleMaterial.ARROW,
|
||||||
|
TextUtils.formatText("&cRemove the last line")),
|
||||||
|
(event -> {
|
||||||
|
lore.remove(lastFinal);
|
||||||
|
loot.setEnchants(lore);
|
||||||
|
paint();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.songoda.core.lootables.gui;
|
||||||
|
|
||||||
|
import com.songoda.core.gui.Gui;
|
||||||
|
import com.songoda.core.lootables.loot.Loot;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class GuiEntityEditor extends AbstractGuiListEditor {
|
||||||
|
|
||||||
|
public GuiEntityEditor(Loot loot, Gui returnGui) {
|
||||||
|
super(loot, returnGui);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<String> getData() {
|
||||||
|
return loot.getOnlyDropFor().stream().map(Enum::name).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateData(List<String> list) {
|
||||||
|
loot.setOnlyDropFor(list.stream().map(EntityType::valueOf).collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String validate(String line) {
|
||||||
|
line = line.toUpperCase().trim();
|
||||||
|
try {
|
||||||
|
EntityType.valueOf(line);
|
||||||
|
return line;
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,268 @@
|
|||||||
|
package com.songoda.core.lootables.gui;
|
||||||
|
|
||||||
|
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||||
|
import com.songoda.core.gui.AnvilGui;
|
||||||
|
import com.songoda.core.gui.Gui;
|
||||||
|
import com.songoda.core.gui.GuiUtils;
|
||||||
|
import com.songoda.core.utils.TextUtils;
|
||||||
|
import com.songoda.core.lootables.loot.Loot;
|
||||||
|
import com.songoda.core.lootables.loot.LootBuilder;
|
||||||
|
import com.songoda.core.lootables.loot.LootManager;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class GuiLootEditor extends Gui {
|
||||||
|
|
||||||
|
private final LootManager lootManager;
|
||||||
|
private final Loot loot;
|
||||||
|
private final Gui returnGui;
|
||||||
|
|
||||||
|
public GuiLootEditor(LootManager lootManager, Loot loot, Gui returnGui) {
|
||||||
|
super(6, returnGui);
|
||||||
|
this.lootManager = lootManager;
|
||||||
|
this.loot = loot;
|
||||||
|
this.returnGui = returnGui;
|
||||||
|
setDefaultItem(null);
|
||||||
|
setTitle("Loot Editor");
|
||||||
|
paint();
|
||||||
|
setOnClose((event) ->
|
||||||
|
lootManager.saveLootables(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint() {
|
||||||
|
if (inventory != null)
|
||||||
|
inventory.clear();
|
||||||
|
setActionForRange(0, 0, 5, 9, null);
|
||||||
|
|
||||||
|
setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.OAK_DOOR,
|
||||||
|
TextUtils.formatText("&cBack")),
|
||||||
|
(event) -> {
|
||||||
|
guiManager.showGUI(event.player, returnGui);
|
||||||
|
});
|
||||||
|
|
||||||
|
setButton(9, GuiUtils.createButtonItem(loot.getMaterial() == null ? CompatibleMaterial.BARRIER : loot.getMaterial(),
|
||||||
|
TextUtils.formatText("&7Current Material: &6" + (loot.getMaterial() != null
|
||||||
|
? loot.getMaterial().name() : "None")), TextUtils.formatText(
|
||||||
|
Arrays.asList("",
|
||||||
|
"&8Click to set the material to",
|
||||||
|
"&8the material in your hand.")
|
||||||
|
)), (event) -> {
|
||||||
|
ItemStack stack = event.player.getInventory().getItemInMainHand();
|
||||||
|
loot.setMaterial(CompatibleMaterial.getMaterial(stack));
|
||||||
|
paint();
|
||||||
|
});
|
||||||
|
|
||||||
|
setButton(10, GuiUtils.createButtonItem(CompatibleMaterial.PAPER,
|
||||||
|
TextUtils.formatText("&7Name Override: &6" + (loot.getName() == null ? "None set" : loot.getName()))),
|
||||||
|
(event) -> {
|
||||||
|
AnvilGui gui = new AnvilGui(event.player, this);
|
||||||
|
gui.setAction((e -> {
|
||||||
|
loot.setName(gui.getInputText().trim());
|
||||||
|
paint();
|
||||||
|
e.player.closeInventory();
|
||||||
|
}));
|
||||||
|
guiManager.showGUI(event.player, gui);
|
||||||
|
gui.setInput(GuiUtils.createButtonItem(CompatibleMaterial.PAPER, loot.getName()));
|
||||||
|
});
|
||||||
|
|
||||||
|
setButton(11, GuiUtils.createButtonItem(CompatibleMaterial.WRITABLE_BOOK,
|
||||||
|
TextUtils.formatText("&7Lore Override:"),
|
||||||
|
TextUtils.formatText(loot.getLore() == null ? Collections.singletonList("&6None set") : loot.getLore())),
|
||||||
|
(event) -> guiManager.showGUI(event.player, new GuiLoreEditor(loot, this)));
|
||||||
|
|
||||||
|
List<String> enchantments = new ArrayList<>();
|
||||||
|
|
||||||
|
if (loot.getEnchants() != null)
|
||||||
|
for (Map.Entry<String, Integer> entry : loot.getEnchants().entrySet())
|
||||||
|
enchantments.add("&6" + entry.getKey() + " " + entry.getValue());
|
||||||
|
|
||||||
|
setButton(12, GuiUtils.createButtonItem(CompatibleMaterial.ENCHANTED_BOOK,
|
||||||
|
TextUtils.formatText("&7Enchantments:"),
|
||||||
|
TextUtils.formatText(enchantments.isEmpty() ? Collections.singletonList("&6None set") : enchantments)),
|
||||||
|
(event) -> guiManager.showGUI(event.player, new GuiEnchantEditor(loot, this)));
|
||||||
|
|
||||||
|
setButton(13, GuiUtils.createButtonItem(
|
||||||
|
loot.getBurnedMaterial() == null
|
||||||
|
? CompatibleMaterial.FIRE_CHARGE
|
||||||
|
: loot.getBurnedMaterial(),
|
||||||
|
TextUtils.formatText("&7Current Burned Material: &6"
|
||||||
|
+ (loot.getBurnedMaterial() == null
|
||||||
|
? "None"
|
||||||
|
: loot.getBurnedMaterial().name())), TextUtils.formatText(
|
||||||
|
Arrays.asList("",
|
||||||
|
"&8Click to set the burned material to",
|
||||||
|
"&8the material in your hand.")
|
||||||
|
)),
|
||||||
|
(event) -> {
|
||||||
|
ItemStack stack = event.player.getInventory().getItemInMainHand();
|
||||||
|
loot.setBurnedMaterial(CompatibleMaterial.getMaterial(stack));
|
||||||
|
paint();
|
||||||
|
});
|
||||||
|
|
||||||
|
setButton(14, GuiUtils.createButtonItem(CompatibleMaterial.CLOCK,
|
||||||
|
TextUtils.formatText("&7Chance: &6" + loot.getChance()),
|
||||||
|
TextUtils.formatText(
|
||||||
|
Arrays.asList("",
|
||||||
|
"&8Click to edit this loots",
|
||||||
|
"&8drop chance.")
|
||||||
|
)),
|
||||||
|
(event) -> {
|
||||||
|
AnvilGui gui = new AnvilGui(event.player, this);
|
||||||
|
gui.setAction((e) -> {
|
||||||
|
loot.setChance(Double.parseDouble(gui.getInputText()));
|
||||||
|
paint();
|
||||||
|
e.player.closeInventory();
|
||||||
|
});
|
||||||
|
gui.setInput(GuiUtils.createButtonItem(CompatibleMaterial.PAPER,
|
||||||
|
String.valueOf(loot.getChance())));
|
||||||
|
guiManager.showGUI(event.player, gui);
|
||||||
|
});
|
||||||
|
|
||||||
|
setButton(15, GuiUtils.createButtonItem(CompatibleMaterial.REDSTONE,
|
||||||
|
TextUtils.formatText("&7Min Drop Amount: &6" + loot.getMin())),
|
||||||
|
(event) -> {
|
||||||
|
AnvilGui gui = new AnvilGui(event.player, this);
|
||||||
|
gui.setAction((e) -> {
|
||||||
|
loot.setMin(Integer.parseInt(gui.getInputText()));
|
||||||
|
paint();
|
||||||
|
e.player.closeInventory();
|
||||||
|
});
|
||||||
|
gui.setInput(GuiUtils.createButtonItem(CompatibleMaterial.PAPER,
|
||||||
|
String.valueOf(loot.getMin())));
|
||||||
|
guiManager.showGUI(event.player, gui);
|
||||||
|
});
|
||||||
|
|
||||||
|
setButton(16, GuiUtils.createButtonItem(CompatibleMaterial.GLOWSTONE_DUST,
|
||||||
|
TextUtils.formatText("&7Max Drop Amount: &6" + loot.getMax())),
|
||||||
|
(event) -> {
|
||||||
|
AnvilGui gui = new AnvilGui(event.player, this);
|
||||||
|
gui.setAction((e) -> {
|
||||||
|
loot.setMax(Integer.parseInt(gui.getInputText()));
|
||||||
|
paint();
|
||||||
|
e.player.closeInventory();
|
||||||
|
});
|
||||||
|
gui.setInput(GuiUtils.createButtonItem(CompatibleMaterial.PAPER,
|
||||||
|
String.valueOf(loot.getMax())));
|
||||||
|
guiManager.showGUI(event.player, gui);
|
||||||
|
});
|
||||||
|
|
||||||
|
setButton(17, GuiUtils.createButtonItem(CompatibleMaterial.REDSTONE,
|
||||||
|
TextUtils.formatText("&7Min Item Damage: &6" + loot.getDamageMin())),
|
||||||
|
(event) -> {
|
||||||
|
AnvilGui gui = new AnvilGui(event.player, this);
|
||||||
|
gui.setAction((e) -> {
|
||||||
|
loot.setDamageMin(Integer.parseInt(gui.getInputText()));
|
||||||
|
paint();
|
||||||
|
e.player.closeInventory();
|
||||||
|
});
|
||||||
|
gui.setInput(GuiUtils.createButtonItem(CompatibleMaterial.PAPER,
|
||||||
|
String.valueOf(loot.getDamageMin())));
|
||||||
|
guiManager.showGUI(event.player, gui);
|
||||||
|
});
|
||||||
|
|
||||||
|
setButton(18, GuiUtils.createButtonItem(CompatibleMaterial.GLOWSTONE_DUST,
|
||||||
|
TextUtils.formatText("&7Max Item Damage: &6" + loot.getDamageMax())),
|
||||||
|
(event) -> {
|
||||||
|
AnvilGui gui = new AnvilGui(event.player, this);
|
||||||
|
gui.setAction((e) -> {
|
||||||
|
loot.setDamageMax(Integer.parseInt(gui.getInputText()));
|
||||||
|
paint();
|
||||||
|
e.player.closeInventory();
|
||||||
|
});
|
||||||
|
gui.setInput(GuiUtils.createButtonItem(CompatibleMaterial.PAPER,
|
||||||
|
String.valueOf(loot.getDamageMax())));
|
||||||
|
guiManager.showGUI(event.player, gui);
|
||||||
|
});
|
||||||
|
|
||||||
|
setButton(19, GuiUtils.createButtonItem(CompatibleMaterial.CHEST,
|
||||||
|
TextUtils.formatText("&7Allow Looting Enchantment?: &6" + loot.isAllowLootingEnchant())),
|
||||||
|
(event) -> {
|
||||||
|
loot.setAllowLootingEnchant(!loot.isAllowLootingEnchant());
|
||||||
|
paint();
|
||||||
|
event.player.closeInventory();
|
||||||
|
});
|
||||||
|
|
||||||
|
setButton(20, GuiUtils.createButtonItem(CompatibleMaterial.REDSTONE,
|
||||||
|
TextUtils.formatText("&7Min Child Loot Min: &6" + loot.getChildDropCountMin())),
|
||||||
|
(event) -> {
|
||||||
|
AnvilGui gui = new AnvilGui(event.player, this);
|
||||||
|
gui.setAction((e) -> {
|
||||||
|
loot.setChildDropCountMin(Integer.parseInt(gui.getInputText()));
|
||||||
|
paint();
|
||||||
|
e.player.closeInventory();
|
||||||
|
});
|
||||||
|
gui.setInput(GuiUtils.createButtonItem(CompatibleMaterial.PAPER,
|
||||||
|
String.valueOf(loot.getChildDropCountMin())));
|
||||||
|
guiManager.showGUI(event.player, gui);
|
||||||
|
});
|
||||||
|
|
||||||
|
setButton(21, GuiUtils.createButtonItem(CompatibleMaterial.GLOWSTONE_DUST,
|
||||||
|
TextUtils.formatText("&7Min Child Loot Max: &6" + loot.getChildDropCountMax())),
|
||||||
|
(event) -> {
|
||||||
|
AnvilGui gui = new AnvilGui(event.player, this);
|
||||||
|
gui.setAction((e) -> {
|
||||||
|
loot.setChildDropCountMax(Integer.parseInt(gui.getInputText()));
|
||||||
|
paint();
|
||||||
|
e.player.closeInventory();
|
||||||
|
});
|
||||||
|
gui.setInput(GuiUtils.createButtonItem(CompatibleMaterial.PAPER,
|
||||||
|
String.valueOf(loot.getChildDropCountMax())));
|
||||||
|
guiManager.showGUI(event.player, gui);
|
||||||
|
});
|
||||||
|
|
||||||
|
List<String> entities = new ArrayList<>();
|
||||||
|
|
||||||
|
if (loot.getOnlyDropFor() != null)
|
||||||
|
for (EntityType entity : loot.getOnlyDropFor())
|
||||||
|
entities.add("&6" + entity.name());
|
||||||
|
|
||||||
|
setButton(22, GuiUtils.createButtonItem(CompatibleMaterial.ENCHANTED_BOOK,
|
||||||
|
TextUtils.formatText("&7Only Drop For:"),
|
||||||
|
TextUtils.formatText(entities)),
|
||||||
|
(event) -> guiManager.showGUI(event.player, new GuiEntityEditor(loot, this)));
|
||||||
|
|
||||||
|
setButton(4, 0, GuiUtils.createButtonItem(CompatibleMaterial.LIME_DYE, TextUtils.formatText("&aCreate new Child Loot")),
|
||||||
|
(event -> {
|
||||||
|
AnvilGui gui = new AnvilGui(event.player, this);
|
||||||
|
gui.setAction((event1 -> {
|
||||||
|
try {
|
||||||
|
loot.addChildLoots(new LootBuilder().setMaterial(CompatibleMaterial
|
||||||
|
.valueOf(gui.getInputText().trim())).build());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
event.player.sendMessage("That is not a valid material.");
|
||||||
|
}
|
||||||
|
event.player.closeInventory();
|
||||||
|
paint();
|
||||||
|
}));
|
||||||
|
gui.setTitle("Enter a material");
|
||||||
|
guiManager.showGUI(event.player, gui);
|
||||||
|
}));
|
||||||
|
|
||||||
|
int i = 9 * 5;
|
||||||
|
for (Loot loot : loot.getChildLoot()) {
|
||||||
|
ItemStack item = loot.getMaterial() == null
|
||||||
|
? CompatibleMaterial.BARRIER.getItem()
|
||||||
|
: GuiUtils.createButtonItem(loot.getMaterial(), null,
|
||||||
|
TextUtils.formatText("&6Left click &7to edit"),
|
||||||
|
TextUtils.formatText("&6Right click &7to destroy"));
|
||||||
|
|
||||||
|
setButton(i, item,
|
||||||
|
(event) -> {
|
||||||
|
if (event.clickType == ClickType.RIGHT) {
|
||||||
|
this.loot.removeChildLoot(loot);
|
||||||
|
paint();
|
||||||
|
} else if (event.clickType == ClickType.LEFT) {
|
||||||
|
guiManager.showGUI(event.player, new GuiLootEditor(lootManager, loot, this));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package com.songoda.core.lootables.gui;
|
||||||
|
|
||||||
|
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||||
|
import com.songoda.core.gui.AnvilGui;
|
||||||
|
import com.songoda.core.gui.Gui;
|
||||||
|
import com.songoda.core.gui.GuiUtils;
|
||||||
|
import com.songoda.core.utils.TextUtils;
|
||||||
|
import com.songoda.core.lootables.loot.Loot;
|
||||||
|
import com.songoda.core.lootables.loot.LootBuilder;
|
||||||
|
import com.songoda.core.lootables.loot.LootManager;
|
||||||
|
import com.songoda.core.lootables.loot.Lootable;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public class GuiLootableEditor extends Gui {
|
||||||
|
|
||||||
|
private final LootManager lootManager;
|
||||||
|
private final Lootable lootable;
|
||||||
|
private final Gui returnGui;
|
||||||
|
|
||||||
|
public GuiLootableEditor(LootManager lootManager, Lootable lootable, Gui returnGui) {
|
||||||
|
super(6);
|
||||||
|
this.lootManager = lootManager;
|
||||||
|
this.lootable = lootable;
|
||||||
|
this.returnGui = returnGui;
|
||||||
|
setOnClose((event) ->
|
||||||
|
lootManager.saveLootables(false));
|
||||||
|
setDefaultItem(null);
|
||||||
|
setTitle("Lootables Editor");
|
||||||
|
paint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void paint() {
|
||||||
|
if (inventory != null)
|
||||||
|
inventory.clear();
|
||||||
|
setActionForRange(0, 0, 5, 9, null);
|
||||||
|
|
||||||
|
setButton(0, GuiUtils.createButtonItem(CompatibleMaterial.LIME_DYE, TextUtils.formatText("&aCreate new Loot")),
|
||||||
|
(event -> {
|
||||||
|
AnvilGui gui = new AnvilGui(event.player, this);
|
||||||
|
gui.setAction((event1 -> {
|
||||||
|
try {
|
||||||
|
lootable.registerLoot(new LootBuilder().setMaterial(CompatibleMaterial
|
||||||
|
.valueOf(gui.getInputText().trim())).build());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
event.player.sendMessage("That is not a valid material.");
|
||||||
|
}
|
||||||
|
event.player.closeInventory();
|
||||||
|
paint();
|
||||||
|
}));
|
||||||
|
gui.setTitle("Enter a material");
|
||||||
|
guiManager.showGUI(event.player, gui);
|
||||||
|
}));
|
||||||
|
|
||||||
|
setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.OAK_DOOR, TextUtils.formatText("&cBack")),
|
||||||
|
(event -> guiManager.showGUI(event.player, returnGui)));
|
||||||
|
|
||||||
|
int i = 9;
|
||||||
|
for (Loot loot : lootable.getRegisteredLoot()) {
|
||||||
|
ItemStack item = loot.getMaterial() == null
|
||||||
|
? CompatibleMaterial.BARRIER.getItem()
|
||||||
|
: GuiUtils.createButtonItem(loot.getMaterial(), null,
|
||||||
|
TextUtils.formatText("&6Left click &7to edit"),
|
||||||
|
TextUtils.formatText("&6Right click &7to destroy"));
|
||||||
|
|
||||||
|
setButton(i, item,
|
||||||
|
(event) -> {
|
||||||
|
if (event.clickType == ClickType.RIGHT) {
|
||||||
|
lootable.removeLoot(loot);
|
||||||
|
paint();
|
||||||
|
} else if (event.clickType == ClickType.LEFT) {
|
||||||
|
guiManager.showGUI(event.player, new GuiLootEditor(lootManager, loot, this));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.songoda.core.lootables.gui;
|
||||||
|
|
||||||
|
import com.songoda.core.gui.Gui;
|
||||||
|
import com.songoda.core.lootables.loot.Loot;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GuiLoreEditor extends AbstractGuiListEditor {
|
||||||
|
|
||||||
|
public GuiLoreEditor(Loot loot, Gui returnGui) {
|
||||||
|
super(loot, returnGui);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<String> getData() {
|
||||||
|
return loot.getLore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateData(List<String> list) {
|
||||||
|
loot.setLore(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String validate(String line) {
|
||||||
|
return line.trim();
|
||||||
|
}
|
||||||
|
}
|
48
Core/src/main/java/com/songoda/core/lootables/loot/Drop.java
Normal file
48
Core/src/main/java/com/songoda/core/lootables/loot/Drop.java
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package com.songoda.core.lootables.loot;
|
||||||
|
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public class Drop {
|
||||||
|
|
||||||
|
private ItemStack itemStack;
|
||||||
|
|
||||||
|
private String command;
|
||||||
|
|
||||||
|
private int xp;
|
||||||
|
|
||||||
|
public Drop(ItemStack itemStack) {
|
||||||
|
this.itemStack = itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Drop(String command) {
|
||||||
|
this.command = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Drop(int xp) {
|
||||||
|
this.xp = xp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCommand() {
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCommand(String command) {
|
||||||
|
this.command = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getXp() {
|
||||||
|
return xp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setXp(int xp) {
|
||||||
|
this.xp = xp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack getItemStack() {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItemStack(ItemStack itemStack) {
|
||||||
|
this.itemStack = itemStack;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.songoda.core.lootables.loot;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.event.entity.EntityDeathEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DropUtils {
|
||||||
|
|
||||||
|
public static void processStackedDrop(LivingEntity entity, List<Drop> drops, EntityDeathEvent event) {
|
||||||
|
int xpToDrop = event.getDroppedExp();
|
||||||
|
List<ItemStack> items = new ArrayList<>();
|
||||||
|
List<String> commands = new ArrayList<>();
|
||||||
|
List<Integer> xp = new ArrayList<>();
|
||||||
|
for (Drop drop : drops) {
|
||||||
|
if (drop == null) continue;
|
||||||
|
|
||||||
|
ItemStack droppedItem = drop.getItemStack();
|
||||||
|
if (droppedItem != null) {
|
||||||
|
droppedItem = droppedItem.clone();
|
||||||
|
boolean success = false;
|
||||||
|
for (ItemStack item : items) {
|
||||||
|
if (item.getType() != droppedItem.getType()
|
||||||
|
|| item.getDurability() != droppedItem.getDurability()
|
||||||
|
|| item.getAmount() + droppedItem.getAmount() > droppedItem.getMaxStackSize()) continue;
|
||||||
|
item.setAmount(item.getAmount() + droppedItem.getAmount());
|
||||||
|
success = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!success)
|
||||||
|
items.add(droppedItem);
|
||||||
|
}
|
||||||
|
if (drop.getCommand() != null)
|
||||||
|
commands.add(drop.getCommand());
|
||||||
|
|
||||||
|
if (drop.getXp() != 0)
|
||||||
|
xp.add(drop.getXp());
|
||||||
|
}
|
||||||
|
|
||||||
|
event.getDrops().clear();
|
||||||
|
|
||||||
|
if (!items.isEmpty())
|
||||||
|
dropItems(items, event);
|
||||||
|
else if (!commands.isEmpty())
|
||||||
|
runCommands(entity, commands);
|
||||||
|
|
||||||
|
for (int x : xp)
|
||||||
|
xpToDrop += x;
|
||||||
|
event.setDroppedExp(xpToDrop);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void dropItems(List<ItemStack> items, EntityDeathEvent event) {
|
||||||
|
for (ItemStack item : items)
|
||||||
|
event.getDrops().add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runCommands(LivingEntity entity, List<String> commands) {
|
||||||
|
for (String command : commands) {
|
||||||
|
if (entity.getKiller() != null)
|
||||||
|
command = command.replace("%player%", entity.getKiller().getName());
|
||||||
|
if (!command.contains("%player%"))
|
||||||
|
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
314
Core/src/main/java/com/songoda/core/lootables/loot/Loot.java
Normal file
314
Core/src/main/java/com/songoda/core/lootables/loot/Loot.java
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
package com.songoda.core.lootables.loot;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||||
|
import com.songoda.core.utils.ItemUtils;
|
||||||
|
import com.songoda.core.utils.TextUtils;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class Loot {
|
||||||
|
|
||||||
|
// Command ran for this drop.
|
||||||
|
@SerializedName("Command")
|
||||||
|
private String command;
|
||||||
|
|
||||||
|
// Xp for this drop.
|
||||||
|
@SerializedName("xp")
|
||||||
|
private int xp = 0;
|
||||||
|
|
||||||
|
// Material used for this drop.
|
||||||
|
@SerializedName("Type")
|
||||||
|
private CompatibleMaterial material;
|
||||||
|
|
||||||
|
// The override for the item name.
|
||||||
|
@SerializedName("Name")
|
||||||
|
private String name = null;
|
||||||
|
|
||||||
|
// The override for the item lore.
|
||||||
|
@SerializedName("Lore")
|
||||||
|
private List<String> lore = null;
|
||||||
|
|
||||||
|
// The override for the item enchantments.
|
||||||
|
@SerializedName("Enchantments")
|
||||||
|
private Map<String, Integer> enchants = null;
|
||||||
|
|
||||||
|
// Material used if entity died on fire.
|
||||||
|
@SerializedName("Burned Type")
|
||||||
|
private CompatibleMaterial 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;
|
||||||
|
|
||||||
|
// The override for chances applied by the wield item.
|
||||||
|
@SerializedName("Wielded Enchantment Chance Overrides")
|
||||||
|
private Map<String, Double> enchantChances = null;
|
||||||
|
|
||||||
|
// Min amount of applied damage.
|
||||||
|
@SerializedName("Damage Min")
|
||||||
|
private Integer damageMin = null;
|
||||||
|
|
||||||
|
// Max amount of applied damage.
|
||||||
|
@SerializedName("Damage Max")
|
||||||
|
private Integer damageMax = null;
|
||||||
|
|
||||||
|
// 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<EntityType> 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<Loot> childLoot;
|
||||||
|
|
||||||
|
// Should the entity be charged? (Only works on creepers)
|
||||||
|
private boolean requireCharged = false;
|
||||||
|
|
||||||
|
public CompatibleMaterial getMaterial() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaterial(CompatibleMaterial material) {
|
||||||
|
this.material = material;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCommand() {
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCommand(String command) {
|
||||||
|
this.command = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getXp() {
|
||||||
|
return xp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setXp(int xp) {
|
||||||
|
this.xp = xp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return TextUtils.formatText(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getLore() {
|
||||||
|
if (lore == null) return null;
|
||||||
|
List<String> lore = new ArrayList<>();
|
||||||
|
for (String line : this.lore)
|
||||||
|
lore.add(TextUtils.formatText(line));
|
||||||
|
|
||||||
|
return lore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLore(List<String> lore) {
|
||||||
|
this.lore = new ArrayList<>(lore);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack getEnchants(ItemStack item) {
|
||||||
|
if (enchants == null) return null;
|
||||||
|
Map<Enchantment, Integer> enchants = new HashMap<>();
|
||||||
|
for (Map.Entry<String, Integer> entry : this.enchants.entrySet()) {
|
||||||
|
|
||||||
|
if (entry.getValue() == null) continue;
|
||||||
|
|
||||||
|
if (entry.getKey().equalsIgnoreCase("RANDOM")) {
|
||||||
|
item = ItemUtils.applyRandomEnchants(item, entry.getValue());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
enchants.put(Enchantment.getByName(entry.getKey()), entry.getValue());
|
||||||
|
}
|
||||||
|
item.addEnchantments(enchants);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnchants(Map<String, Integer> enchants) {
|
||||||
|
this.enchants = enchants;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setEnchantChances(Map<String, Double> enchants) {
|
||||||
|
this.enchantChances = enchants;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Integer> getEnchants() {
|
||||||
|
return enchants == null ? null : Collections.unmodifiableMap(enchants);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompatibleMaterial getBurnedMaterial() {
|
||||||
|
return burnedMaterial;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBurnedMaterial(CompatibleMaterial burnedMaterial) {
|
||||||
|
this.burnedMaterial = burnedMaterial;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getChance() {
|
||||||
|
return chance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChance(double chance) {
|
||||||
|
this.chance = chance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean runChance(int looting, ItemStack murderWeapon) {
|
||||||
|
double chance = this.chance;
|
||||||
|
if (enchantChances != null && murderWeapon != null && enchants != null) {
|
||||||
|
for (Map.Entry<Enchantment, Integer> entry : murderWeapon.getEnchantments().entrySet()) {
|
||||||
|
String key = entry.getKey().getName() + ":" + entry.getValue();
|
||||||
|
if (!enchants.containsKey(key)) continue;
|
||||||
|
double ch = enchantChances.get(key);
|
||||||
|
if (ch > chance)
|
||||||
|
chance = enchantChances.get(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 getDamageMax() {
|
||||||
|
return damageMax == null ? 0 : damageMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDamageMax(int damageMax) {
|
||||||
|
this.damageMax = damageMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDamageMin() {
|
||||||
|
return damageMin == null ? 0 : damageMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDamageMin(int damageMin) {
|
||||||
|
this.damageMin = damageMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 void addChildLoots(Loot... loots) {
|
||||||
|
this.childDropCountMin = 1;
|
||||||
|
this.childDropCountMax = 1;
|
||||||
|
if (childLoot == null)
|
||||||
|
this.childLoot = new ArrayList<>();
|
||||||
|
this.childLoot.addAll(Arrays.asList(loots));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeChildLoot(Loot loot) {
|
||||||
|
if (childLoot == null) return;
|
||||||
|
this.childLoot.remove(loot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Loot> getChildLoot() {
|
||||||
|
return childLoot == null ? new ArrayList<>() : new ArrayList<>(childLoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EntityType> getOnlyDropFor() {
|
||||||
|
return onlyDropFor == null ? new ArrayList<>() : new ArrayList<>(onlyDropFor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addOnlyDropFor(EntityType... types) {
|
||||||
|
this.onlyDropFor = new ArrayList<>();
|
||||||
|
this.onlyDropFor.addAll(Arrays.asList(types));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnlyDropFor(List<EntityType> types) {
|
||||||
|
this.onlyDropFor = types;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChildDropCountMin(int childDropCountMin) {
|
||||||
|
this.childDropCountMin = childDropCountMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChildDropCountMax(int childDropCountMax) {
|
||||||
|
this.childDropCountMax = childDropCountMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getChildDropCountMin() {
|
||||||
|
return childDropCountMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getChildDropCountMax() {
|
||||||
|
return childDropCountMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChildDropCount() {
|
||||||
|
if (childDropCountMin == null || childDropCountMax == null) return 0;
|
||||||
|
return new Random().nextInt(childDropCountMax - childDropCountMin + 1) + childDropCountMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRequireCharged() {
|
||||||
|
return requireCharged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequireCharged(boolean requireCharged) {
|
||||||
|
this.requireCharged = requireCharged;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
package com.songoda.core.lootables.loot;
|
||||||
|
|
||||||
|
|
||||||
|
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||||
|
import com.songoda.core.lootables.loot.objects.EnchantChance;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public final class LootBuilder {
|
||||||
|
|
||||||
|
private final Loot loot;
|
||||||
|
|
||||||
|
public LootBuilder() {
|
||||||
|
this.loot = new Loot();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LootBuilder setMaterial(CompatibleMaterial material) {
|
||||||
|
this.loot.setMaterial(material);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LootBuilder setName(String name) {
|
||||||
|
this.loot.setName(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LootBuilder addLore(String... lore) {
|
||||||
|
this.loot.setLore(Arrays.asList(lore));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LootBuilder addEnchants(Tuple... tuples) {
|
||||||
|
Map<String, Integer> enchants = new HashMap<>();
|
||||||
|
for (Tuple tuple : tuples)
|
||||||
|
enchants.put((String)tuple.getKey(), (int)tuple.getValue());
|
||||||
|
this.loot.setEnchants(enchants);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LootBuilder addEnchantChances(EnchantChance... enchantChances) {
|
||||||
|
Map<String, Double> enchants = new HashMap<>();
|
||||||
|
for (EnchantChance chance : enchantChances)
|
||||||
|
enchants.put(chance.getEnchantment().getName() + ":" + chance.getLevel(), chance.getChanceOverride());
|
||||||
|
this.loot.setEnchantChances(enchants);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LootBuilder setBurnedMaterial(CompatibleMaterial 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 setDamageMin(int min) {
|
||||||
|
this.loot.setDamageMin(min);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LootBuilder setDamageMax(int max) {
|
||||||
|
this.loot.setDamageMax(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.addOnlyDropFor(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 LootBuilder setRequireCharged(boolean require) {
|
||||||
|
this.loot.setRequireCharged(require);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Loot build() {
|
||||||
|
return this.loot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Tuple<key, value> {
|
||||||
|
public final key x;
|
||||||
|
public final value y;
|
||||||
|
|
||||||
|
public Tuple(key x, value y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public key getKey() {
|
||||||
|
return this.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public value getValue() {
|
||||||
|
return this.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,180 @@
|
|||||||
|
package com.songoda.core.lootables.loot;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||||
|
import com.songoda.core.lootables.Lootables;
|
||||||
|
import com.songoda.core.lootables.Modify;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class LootManager {
|
||||||
|
|
||||||
|
private final Map<String, Lootable> registeredLootables = new HashMap<>();
|
||||||
|
|
||||||
|
private final Lootables lootables;
|
||||||
|
|
||||||
|
public LootManager(Lootables lootables) {
|
||||||
|
this.lootables = lootables;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Lootable addLootable(Lootable lootable) {
|
||||||
|
return registeredLootables.put(lootable.getKey(), lootable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeLootable(String key) {
|
||||||
|
registeredLootables.remove(key);
|
||||||
|
File file = new File(lootables.getLootablesDir()
|
||||||
|
+ "/" + key.toLowerCase() + ".json");
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Drop> runLoot(Modify modify, boolean burning, boolean isCharged, ItemStack murderWeapon, EntityType looter, Loot loot, int rerollChance, int looting) {
|
||||||
|
List<Drop> toDrop = new ArrayList<>();
|
||||||
|
if (modify != null)
|
||||||
|
loot = modify.Modify(loot);
|
||||||
|
if (loot == null) return toDrop;
|
||||||
|
|
||||||
|
if (loot.runChance(looting, murderWeapon) || ((Math.random() * 100) - rerollChance < 0 || rerollChance == 100)
|
||||||
|
&& loot.runChance(looting, murderWeapon)) {
|
||||||
|
|
||||||
|
if (loot.getOnlyDropFor().size() != 0
|
||||||
|
&& loot.getOnlyDropFor().stream().noneMatch(type -> looter != null && type == looter)
|
||||||
|
|| !isCharged && loot.isRequireCharged())
|
||||||
|
return toDrop;
|
||||||
|
|
||||||
|
if (loot.getChildLoot().size() > 0) {
|
||||||
|
List<Loot> childLoot = loot.getChildLoot();
|
||||||
|
Collections.shuffle(childLoot);
|
||||||
|
|
||||||
|
int amt = loot.getChildDropCount();
|
||||||
|
int success = 0;
|
||||||
|
|
||||||
|
top:
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
for (Loot value : childLoot) {
|
||||||
|
if (value == null) continue;
|
||||||
|
if (amt == success) break top;
|
||||||
|
List<Drop> drops = runLoot(modify, burning, isCharged, murderWeapon, looter, value, rerollChance, looting);
|
||||||
|
if (!drops.isEmpty()) success++;
|
||||||
|
toDrop.addAll(drops);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CompatibleMaterial material = loot.getMaterial();
|
||||||
|
String command = loot.getCommand();
|
||||||
|
int xp = loot.getXp();
|
||||||
|
|
||||||
|
if (material == null && command == null) return toDrop;
|
||||||
|
|
||||||
|
int amount = loot.getAmountToDrop(looting);
|
||||||
|
if (amount == 0) return toDrop;
|
||||||
|
|
||||||
|
if (material != null) {
|
||||||
|
ItemStack item = loot.getBurnedMaterial() != null && burning
|
||||||
|
? loot.getBurnedMaterial().getItem() : material.getItem();
|
||||||
|
item.setAmount(amount);
|
||||||
|
ItemMeta meta = item.getItemMeta() == null ? Bukkit.getItemFactory().getItemMeta(loot.getMaterial().getMaterial())
|
||||||
|
: item.getItemMeta();
|
||||||
|
|
||||||
|
if (loot.getName() != null)
|
||||||
|
meta.setDisplayName(loot.getName());
|
||||||
|
|
||||||
|
if (loot.getLore() != null)
|
||||||
|
meta.setLore(loot.getLore());
|
||||||
|
item.setItemMeta(meta);
|
||||||
|
|
||||||
|
if (loot.getEnchants(item) != null)
|
||||||
|
item = loot.getEnchants(item);
|
||||||
|
|
||||||
|
if (loot.getDamageMax() != 0 && loot.getDamageMin() != 0) {
|
||||||
|
short max = item.getType().getMaxDurability();
|
||||||
|
short min = (short) (max * (10 / 100.0f));
|
||||||
|
item.setDurability((short) (new Random().nextInt(max - min + 1) + min));
|
||||||
|
}
|
||||||
|
|
||||||
|
toDrop.add(new Drop(item));
|
||||||
|
}
|
||||||
|
if (command != null) {
|
||||||
|
for (int i = 0; i < amount; i++)
|
||||||
|
toDrop.add(new Drop(command));
|
||||||
|
}
|
||||||
|
if (xp != 0) {
|
||||||
|
for (int i = 0; i < amount; i++)
|
||||||
|
toDrop.add(new Drop(xp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return toDrop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadLootables() {
|
||||||
|
registeredLootables.clear();
|
||||||
|
File dir = new File(lootables.getLootablesDir());
|
||||||
|
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);
|
||||||
|
|
||||||
|
reader.close();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveLootables(boolean defaults) {
|
||||||
|
File dir = new File(lootables.getLootablesDir());
|
||||||
|
dir.mkdir();
|
||||||
|
|
||||||
|
// Save to file
|
||||||
|
for (Lootable lootable : registeredLootables.values()) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
File file = new File(lootables.getLootablesDir()
|
||||||
|
+ "/" + lootable.getKey().toLowerCase() + ".json");
|
||||||
|
if (file.exists() && defaults) continue;
|
||||||
|
|
||||||
|
try (Writer writer = new FileWriter(file.getPath())) {
|
||||||
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
gson.toJson(lootable, writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defaults)
|
||||||
|
registeredLootables.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Lootable> getRegisteredLootables() {
|
||||||
|
return Collections.unmodifiableMap(registeredLootables);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.songoda.core.lootables.loot;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Lootable {
|
||||||
|
|
||||||
|
// The key applicable to this lootable.
|
||||||
|
@SerializedName("Type")
|
||||||
|
private final String type;
|
||||||
|
|
||||||
|
// Registered loot.
|
||||||
|
@SerializedName("Loot")
|
||||||
|
private final List<Loot> registeredLoot = new ArrayList<>();
|
||||||
|
|
||||||
|
public Lootable(String key) {
|
||||||
|
this.type = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Lootable(String key, Loot... loots) {
|
||||||
|
this.type = key;
|
||||||
|
registeredLoot.addAll(Arrays.asList(loots));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Loot> getRegisteredLoot() {
|
||||||
|
return new ArrayList<>(registeredLoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerLoot(Loot... loots) {
|
||||||
|
registeredLoot.addAll(Arrays.asList(loots));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeLoot(Loot loot) {
|
||||||
|
this.registeredLoot.remove(loot);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.songoda.core.lootables.loot.objects;
|
||||||
|
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
|
||||||
|
public class EnchantChance {
|
||||||
|
|
||||||
|
private final Enchantment enchantment;
|
||||||
|
private final int level;
|
||||||
|
private final double chanceOverride;
|
||||||
|
|
||||||
|
public EnchantChance(Enchantment enchantment, int level, double chanceOverride) {
|
||||||
|
this.enchantment = enchantment;
|
||||||
|
this.level = level;
|
||||||
|
this.chanceOverride = chanceOverride;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enchantment getEnchantment() {
|
||||||
|
return enchantment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getChanceOverride() {
|
||||||
|
return chanceOverride;
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,7 @@ import java.lang.reflect.Method;
|
|||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@ -77,6 +78,43 @@ public class ItemUtils {
|
|||||||
return titleCase.toString().trim();
|
return titleCase.toString().trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Method methodAsBukkitCopy, methodAsNMSCopy, methodA;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
Class<?> clazzEnchantmentManager = ClassMapping.ENCHANTMENT_MANAGER.getClazz();
|
||||||
|
Class<?> clazzItemStack = ClassMapping.ITEM_STACK.getClazz();
|
||||||
|
Class<?> clazzCraftItemStack = ClassMapping.CRAFT_ITEM_STACK.getClazz();
|
||||||
|
|
||||||
|
methodAsBukkitCopy = clazzCraftItemStack.getMethod("asBukkitCopy", clazzItemStack);
|
||||||
|
methodAsNMSCopy = clazzCraftItemStack.getMethod("asNMSCopy", ItemStack.class);
|
||||||
|
|
||||||
|
if (ServerVersion.isServerVersion(ServerVersion.V1_8))
|
||||||
|
methodA = clazzEnchantmentManager.getMethod("a", Random.class, clazzItemStack, int.class);
|
||||||
|
else
|
||||||
|
methodA = clazzEnchantmentManager.getMethod("a", Random.class, clazzItemStack, int.class, boolean.class);
|
||||||
|
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemStack applyRandomEnchants(ItemStack item, int level) {
|
||||||
|
try {
|
||||||
|
Object nmsItemStack = methodAsNMSCopy.invoke(null, item);
|
||||||
|
|
||||||
|
if (ServerVersion.isServerVersion(ServerVersion.V1_8))
|
||||||
|
nmsItemStack = methodA.invoke(null, new Random(), nmsItemStack, level);
|
||||||
|
else
|
||||||
|
nmsItemStack = methodA.invoke(null, new Random(), nmsItemStack, level, false);
|
||||||
|
|
||||||
|
item = (ItemStack) methodAsBukkitCopy.invoke(null, nmsItemStack);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
public static String itemStackArrayToBase64(ItemStack[] items) {
|
public static String itemStackArrayToBase64(ItemStack[] items) {
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
Loading…
Reference in New Issue
Block a user