package ttftcuts.physis.api.internal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import ttftcuts.physis.api.PhysisAPI;
import net.minecraft.item.ItemStack;
import net.minecraft.util.WeightedRandomChestContent;
import net.minecraftforge.common.ChestGenHooks;
import net.minecraftforge.oredict.OreDictionary;
public class LootList {
public void addItemStack(ItemStack stack, int minCount, int maxCount, int price, double weight) {
this.list.add(new LootEntry(stack, minCount, maxCount, price, weight));
}
public void addItemStack(ItemStack stack, int minCount, int maxCount, int price) {
this.addItemStack(stack, minCount, maxCount, price, 1.0);
}
public void addItemStackChestGen(ItemStack stack, int minCount, int maxCount, int price, double weight) {
this.list.add(new LootEntry(stack, minCount, maxCount, price, weight, true));
}
public void addItemStackChestGen(ItemStack stack, int minCount, int maxCount, int price) {
this.addItemStackChestGen(stack, minCount, maxCount, price, 1.0);
}
public void addChest(ChestGenHooks chest, int price, double weight) {
this.list.add(new LootEntry(chest, price, weight));
}
public void addChest(ChestGenHooks chest, int price) {
this.addChest(chest, price, 1.0);
}
public void addOrePrefix(String prefix, int minCount, int maxCount, int price, double weight) {
this.list.add(new LootEntry(prefix, minCount, maxCount, price, weight));
}
public void addOrePrefix(String prefix, int minCount, int maxCount, int price) {
this.addOrePrefix(prefix, minCount, maxCount, price, 1.0);
}
// -------------------------------------
private List<LootEntry> list;
public LootList() {
this.list = new ArrayList<LootEntry>();
}
private List<LootEntry> getLootRange(int minValue, int maxValue) {
List<LootEntry> filtered = new ArrayList<LootEntry>();
for (LootEntry entry : this.list) {
if (entry.price >= minValue && entry.price <= maxValue) {
filtered.add(entry);
}
}
return filtered;
}
public List<ItemStack> getLoot(Random rand, int budget, int primeMinValue, int minValue, int maxValue) {
List<ItemStack> loot = new ArrayList<ItemStack>();
boolean first = true;
while (budget > 0) {
int min = (first) ? primeMinValue : minValue;
int max = Math.min(budget, maxValue);
List<LootEntry> lootlist = getLootRange(min, max);
if (first && lootlist.isEmpty()) {
lootlist = getLootRange(Math.min(budget, minValue), max);
}
if (lootlist.size() == 0) { break; }
double totalweight = 0;
for (int i=0; i<lootlist.size(); i++) {
totalweight += lootlist.get(i).weight;
}
double roll = rand.nextDouble() * totalweight;
double currentweight = 0;
LootEntry lootitem = null;
for (int i=0; i<lootlist.size(); i++) {
LootEntry e = lootlist.get(i);
currentweight += e.weight;
if (currentweight >= roll) {
lootitem = e;
break;
}
}
if (lootitem == null) { continue; }
loot.addAll(lootitem.getLoot(rand));
budget -= lootitem.price;
first = false;
}
return loot;
}
private enum LootType {
NONE,
ITEMSTACK,
ITEMSTACKCHESTGEN,
CHEST,
OREPREFIX
}
private class LootEntry {
public LootType type = LootType.NONE;
public int price = 0;
public double weight = 1.0;
public ItemStack stack;
public ChestGenHooks chest;
public String oreprefix;
private List<ItemStack> ores;
public int min, max;
public LootEntry(int min, int max, int price, double weight) {
this.min = min;
this.max = max;
this.price = price;
this.weight = weight;
}
public LootEntry(ItemStack stack, int min, int max, int price, double weight) {
this(stack, min, max, price, weight, false);
}
public LootEntry(ItemStack stack, int min, int max, int price, double weight, boolean chestGen) {
this(min, max, price, weight);
this.type = chestGen ? LootType.ITEMSTACKCHESTGEN : LootType.ITEMSTACK;
this.stack = stack;
}
public LootEntry(ChestGenHooks chest, int price, double weight) {
this(1, 1, price, weight);
this.type = LootType.CHEST;
this.chest = chest;
}
public LootEntry(String oreprefix, int min, int max, int price, double weight) {
this(min, max, price, weight);
this.type = LootType.OREPREFIX;
this.oreprefix = oreprefix;
}
public List<ItemStack> getLoot(Random rand) {
List<ItemStack> lootlist = new ArrayList<ItemStack>();
int diff = this.max - this.min;
int num = diff == 0 ? this.min : (rand.nextInt(this.max - this.min) + this.min);
switch(this.type) {
case ITEMSTACK:
for (int i=0; i<num; i++) {
ItemStack loot = this.stack.copy();
lootlist.add(loot);
}
break;
case ITEMSTACKCHESTGEN:
for (int i=0; i<num; i++) {
WeightedRandomChestContent c = new WeightedRandomChestContent(this.stack.copy(), 1,1,1);
c = this.stack.getItem().getChestGenBase(ChestGenHooks.getInfo(ChestGenHooks.DUNGEON_CHEST), rand, c);
ItemStack[] stacks = ChestGenHooks.generateStacks(rand, c.theItemId, 1, 1);
if (stacks.length > 0) {
lootlist.add(stacks[0]);
}
}
break;
case CHEST:
lootlist.add(this.chest.getOneItem(rand));
break;
case OREPREFIX:
if (ores == null) {
this.ores = new ArrayList<ItemStack>();
String[] orenames = OreDictionary.getOreNames();
for (String orename : orenames) {
if (PhysisAPI.forbiddenOreNames.contains(orename)) {
continue;
}
if (orename.startsWith(this.oreprefix)) {
this.ores.addAll(OreDictionary.getOres(orename));
}
}
}
if (ores.size() == 0) { break; }
ItemStack stack = this.ores.get(rand.nextInt(this.ores.size())).copy();
if (stack != null) {
stack.stackSize = num;
lootlist.add(stack);
}
break;
default:
}
return lootlist;
}
}
}