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);