From b080a6ffc2aa25bd3ec70058e32b9a15509a81fc Mon Sep 17 00:00:00 2001 From: Daniel Saukel Date: Sun, 24 Jul 2016 13:43:05 +0200 Subject: [PATCH] Added loot tables. Close #104 --- .../dungeonsxl/loottable/DLootTable.java | 176 ++++++++++++++++++ .../dungeonsxl/loottable/DLootTables.java | 75 ++++++++ .../dre2n/dungeonsxl/reward/RewardChest.java | 2 +- .../dre2n/dungeonsxl/sign/ChestSign.java | 57 ++++-- 4 files changed, 296 insertions(+), 14 deletions(-) create mode 100644 core/src/main/java/io/github/dre2n/dungeonsxl/loottable/DLootTable.java create mode 100644 core/src/main/java/io/github/dre2n/dungeonsxl/loottable/DLootTables.java diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/loottable/DLootTable.java b/core/src/main/java/io/github/dre2n/dungeonsxl/loottable/DLootTable.java new file mode 100644 index 00000000..c8ba5201 --- /dev/null +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/loottable/DLootTable.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2012-2016 Frank Baumann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package io.github.dre2n.dungeonsxl.loottable; + +import io.github.dre2n.caliburn.item.UniversalItemStack; +import io.github.dre2n.commons.util.NumberUtil; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.ItemStack; + +/** + * @author Daniel Saukel + */ +public class DLootTable { + + public class Entry { + + private String id; + private ItemStack item; + private double chance; + + public Entry(String id, ItemStack item, double chance) { + this.id = id; + this.item = item; + this.chance = chance; + } + + /* Getters and setters */ + /** + * @return the id of the loot table entry + */ + public String getId() { + return id; + } + + /** + * @param id + * the id of the loot table entry to set + */ + public void setId(String id) { + this.id = id; + } + + /** + * @return the loot item stack + */ + public ItemStack getLootItem() { + return item; + } + + /** + * @param item + * the loot item to set + */ + public void setLootItem(ItemStack item) { + this.item = item; + } + + /** + * @return the loot chance + */ + public double getLootChance() { + return chance; + } + + /** + * @param chance + * the loot chance to set + */ + public void setLootChance(double chance) { + this.chance = chance; + } + + } + + private String name; + private List entries = new ArrayList<>(); + + /** + * @param file + * the script file + */ + public DLootTable(File file) { + this(file.getName().substring(0, file.getName().length() - 4), YamlConfiguration.loadConfiguration(file)); + } + + /** + * @param name + * the name of the loot table + * @param config + * the config that stores the information + */ + public DLootTable(String name, FileConfiguration config) { + this.name = name; + + for (String id : config.getKeys(true)) { + ItemStack item = null; + Object itemObj = config.get(id + ".item"); + if (itemObj instanceof ItemStack) { + item = (ItemStack) itemObj; + } else if (itemObj instanceof UniversalItemStack) { + item = ((UniversalItemStack) itemObj).toItemStack(); + } else if (itemObj instanceof String) { + item = UniversalItemStack.deserializeSimple((String) itemObj).toItemStack(); + } + + double chance = config.getDouble(id + ".chance"); + entries.add(new Entry(id, item, chance)); + } + } + + /* Getters and setters */ + /** + * @return the name of the loot table + */ + public String getName() { + return name; + } + + /** + * @return the entries + */ + public List getEntries() { + return entries; + } + + /** + * @param entry + * the entry to add + */ + public void addEntry(Entry entry) { + entries.add(entry); + } + + /** + * @param entry + * the entry to remove + */ + public void removeEntry(Entry entry) { + entries.remove(entry); + } + + /* Actions */ + /** + * Adds loot to a list randomly based on the chance value + * + * @return a list of the loot + */ + public List generateLootList() { + List lootList = new ArrayList<>(); + for (Entry entry : entries) { + if (NumberUtil.generateRandomInt(0, 100) < entry.getLootChance()) { + lootList.add(entry.getLootItem()); + } + } + return lootList; + } + +} diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/loottable/DLootTables.java b/core/src/main/java/io/github/dre2n/dungeonsxl/loottable/DLootTables.java new file mode 100644 index 00000000..ce6b412f --- /dev/null +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/loottable/DLootTables.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2012-2016 Frank Baumann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package io.github.dre2n.dungeonsxl.loottable; + +import io.github.dre2n.commons.util.FileUtil; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Daniel Saukel + */ +public class DLootTables { + + private List lootTables = new ArrayList<>(); + + public DLootTables(File file) { + if (file.isDirectory()) { + for (File script : FileUtil.getFilesForFolder(file)) { + lootTables.add(new DLootTable(script)); + } + } + } + + /** + * @return the loot table that has the name + */ + public DLootTable getByName(String name) { + for (DLootTable lootTable : lootTables) { + if (lootTable.getName().equalsIgnoreCase(name)) { + return lootTable; + } + } + + return null; + } + + /** + * @return the loot tables + */ + public List getDLootTables() { + return lootTables; + } + + /** + * @param lootTable + * the DLootTable to add + */ + public void addDLootTable(DLootTable lootTable) { + lootTables.add(lootTable); + } + + /** + * @param lootTable + * the DLootTable to remove + */ + public void removeDLootTable(DLootTable lootTable) { + lootTables.remove(lootTable); + } + +} diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/reward/RewardChest.java b/core/src/main/java/io/github/dre2n/dungeonsxl/reward/RewardChest.java index 3958651b..c4c8850a 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/reward/RewardChest.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/reward/RewardChest.java @@ -202,7 +202,7 @@ public class RewardChest { if (itemReward != null) { String msg = ""; - for (ItemStack itemStack : chest.getInventory().getContents()) { + for (ItemStack itemStack : itemReward) { if (itemStack == null) { continue; diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/sign/ChestSign.java b/core/src/main/java/io/github/dre2n/dungeonsxl/sign/ChestSign.java index 66ede5ae..6816623d 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/sign/ChestSign.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/sign/ChestSign.java @@ -17,8 +17,12 @@ package io.github.dre2n.dungeonsxl.sign; import io.github.dre2n.commons.util.NumberUtil; +import io.github.dre2n.dungeonsxl.loottable.DLootTable; import io.github.dre2n.dungeonsxl.reward.RewardChest; import io.github.dre2n.dungeonsxl.world.DGameWorld; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Chest; @@ -36,7 +40,8 @@ public class ChestSign extends DSign { private double moneyReward; private int levelReward; - private ItemStack[] itemReward; + private ItemStack[] chestContent; + private DLootTable lootTable; public ChestSign(Sign sign, String[] lines, DGameWorld gameWorld) { super(sign, lines, gameWorld); @@ -74,21 +79,36 @@ public class ChestSign extends DSign { } /** - * @return the item reward + * @return the chest contents */ - public ItemStack[] getItemReward() { - if (itemReward == null) { + public ItemStack[] getChestContents() { + if (chestContent == null) { checkChest(); } - return itemReward; + return chestContent; } /** * @param items - * the items to set as a reward + * the items to set as chest contents */ public void setItemReward(ItemStack[] items) { - itemReward = items; + chestContent = items; + } + + /** + * @return the custom loot table + */ + public DLootTable getLootTable() { + return lootTable; + } + + /** + * @param lootTable + * the loot table to set + */ + public void setLootTable(DLootTable lootTable) { + this.lootTable = lootTable; } @Override @@ -108,20 +128,20 @@ public class ChestSign extends DSign { Block zRelative = sign.getRelative(0, 0, i); if (xRelative.getType() == Material.CHEST) { - if (itemReward == null) { - itemReward = ((Chest) xRelative.getState()).getBlockInventory().getContents(); + if (chestContent == null) { + chestContent = ((Chest) xRelative.getState()).getBlockInventory().getContents(); } chest = xRelative; } else if (yRelative.getType() == Material.CHEST) { - if (itemReward == null) { - itemReward = ((Chest) yRelative.getState()).getBlockInventory().getContents(); + if (chestContent == null) { + chestContent = ((Chest) yRelative.getState()).getBlockInventory().getContents(); } chest = yRelative; } else if (zRelative.getType() == Material.CHEST) { - if (itemReward == null) { - itemReward = ((Chest) zRelative.getState()).getBlockInventory().getContents(); + if (chestContent == null) { + chestContent = ((Chest) zRelative.getState()).getBlockInventory().getContents(); } chest = zRelative; } @@ -145,11 +165,22 @@ public class ChestSign extends DSign { } } + if (!lines[2].isEmpty()) { + lootTable = plugin.getDLootTables().getByName(lines[2]); + } + if (chest == null) { checkChest(); } if (chest != null) { + ItemStack[] itemReward = chestContent; + if (lootTable != null) { + List list = new LinkedList<>(Arrays.asList(chestContent)); + list.addAll(lootTable.generateLootList()); + itemReward = list.toArray(new ItemStack[list.size()]); + } + new RewardChest(chest, getGameWorld(), moneyReward, levelReward, itemReward); getSign().getBlock().setType(Material.AIR);