package net.scapeemulator.game.model.npc.drops;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import net.scapeemulator.game.model.player.Item;
/**
* Represents a drop table definition, including various sub tables.
*
* @author David Insley
*/
public class DropTable {
private static final Random RANDOM = new Random();
private Map<TableType, SubDropTable> tables = new HashMap<>();
/**
* Adds a drop table with the default table chance. Overwrites any existing
* table for that type.
*
* @param type the TableType to add
*/
public void addTable(TableType type) {
tables.put(type, new SubDropTable(type.getDefaultChance()));
}
/**
* Adds a drop table with the specified table chance. Overwrites any
* existing table for that type. The chance should be a value between 0
* (inclusive) and 1 (exclusive), with lower values being more rare.
*
* @param type the TableType to add
* @param chance the double chance to use for this table
*/
public void addTable(TableType type, double chance) {
if (type == TableType.ALWAYS) {
throw new IllegalArgumentException("Cannot change drop chance for the always drop table");
}
tables.put(type, new SubDropTable(chance));
}
/**
* Adds a drop to the specified table with the special string amount
* argument. Amount argument should be in the format: "
* <tt>amt1,amt2,amt3min-amt3max,amt4</tt>". More specifically, amounts
* should be separated by commas and ranges specified by dashes.
*
* @param type the table to add the item to
* @param itemId the item id
* @param amount the special amount identifier
*/
public void addItem(TableType type, int itemId, String amount) {
if (!tables.containsKey(type)) {
throw new IllegalArgumentException("Make sure to add the table before adding items.");
}
tables.get(type).addItem(new DropTableItem(itemId, amount));
}
/**
* Adds a drop to the specified table with the given id and amount.
*
* @param type the table to add the item to
* @param itemId the item id
* @param amount the item amount
*/
public void addItem(TableType type, int itemId, int amount) {
if (!tables.containsKey(type)) {
throw new IllegalArgumentException("Make sure to add the table before adding items.");
}
tables.get(type).addItem(new DropTableItem(itemId, amount));
}
/**
* Adds a drop to the specified table with the default amount 1.
*
* @param type the table to add the item to
* @param itemId the item id
*/
public void addItem(TableType type, int itemId) {
addItem(type, itemId, 1);
}
public Map<TableType, SubDropTable> getTables() {
return tables;
}
/**
* Populates a List with the items this table collection randomly generates.
*
* @return the generated random drop list
*/
public List<Item> getRandomDrops() {
List<Item> items = new ArrayList<>();
// Add all of the always drop items
SubDropTable activeTable = tables.get(TableType.ALWAYS);
if (activeTable != null) {
activeTable.addAll(items);
}
// Roll for the normal tables
double roll = RANDOM.nextDouble();
activeTable = null;
for (SubDropTable table : tables.values()) {
if (table.getChance() < roll || table.isEmpty() || (activeTable != null && activeTable.getChance() < table.getChance())) {
continue;
}
activeTable = table;
}
if (activeTable != null) {
activeTable.addRandom(items);
}
// See if they should get an extra drop from the extra table
activeTable = tables.get(TableType.EXTRA);
if (activeTable != null) {
double extraRoll = RANDOM.nextDouble();
if (extraRoll < activeTable.getChance()) {
activeTable.addRandom(items);
}
}
return items;
}
}