add enchantment to loot tables

This commit is contained in:
dfsek
2021-01-09 02:25:36 -07:00
parent 9a94485c91
commit 67ffd91641
15 changed files with 206 additions and 24 deletions

View File

@@ -2,7 +2,14 @@ package com.dfsek.terra.api.platform.handle;
import com.dfsek.terra.api.platform.block.MaterialData;
import com.dfsek.terra.api.platform.inventory.ItemStack;
import com.dfsek.terra.api.platform.inventory.item.Enchantment;
import java.util.Set;
public interface ItemHandle {
ItemStack newItemStack(MaterialData material, int amount);
Enchantment getEnchantment(String id);
Set<Enchantment> getEnchantments();
}

View File

@@ -0,0 +1,14 @@
package com.dfsek.terra.api.platform.inventory.item;
import com.dfsek.terra.api.platform.Handle;
import com.dfsek.terra.api.platform.inventory.ItemStack;
public interface Enchantment extends Handle {
boolean canEnchantItem(ItemStack itemStack);
String getID();
boolean conflictsWith(Enchantment other);
int getMaxLevel();
}

View File

@@ -2,5 +2,10 @@ package com.dfsek.terra.api.platform.inventory.item;
import com.dfsek.terra.api.platform.Handle;
import java.util.Map;
public interface ItemMeta extends Handle {
Map<Enchantment, Integer> getEnchantments();
void addEnchantment(Enchantment enchantment, int level);
}

View File

@@ -5,7 +5,8 @@ import com.dfsek.terra.api.platform.block.MaterialData;
import com.dfsek.terra.api.platform.inventory.ItemStack;
import com.dfsek.terra.api.structures.loot.functions.AmountFunction;
import com.dfsek.terra.api.structures.loot.functions.DamageFunction;
import com.dfsek.terra.api.structures.loot.functions.Function;
import com.dfsek.terra.api.structures.loot.functions.EnchantFunction;
import com.dfsek.terra.api.structures.loot.functions.LootFunction;
import com.dfsek.terra.api.util.GlueList;
import net.jafama.FastMath;
import org.json.simple.JSONArray;
@@ -20,7 +21,7 @@ import java.util.Random;
public class Entry {
private final MaterialData item;
private final long weight;
private final List<Function> functions = new GlueList<>();
private final List<LootFunction> functions = new GlueList<>();
private final TerraPlugin main;
/**
@@ -63,6 +64,15 @@ public class Entry {
long minDamage = (long) ((JSONObject) ((JSONObject) function).get("damage")).get("min");
functions.add(new DamageFunction(FastMath.toIntExact(minDamage), FastMath.toIntExact(maxDamage)));
break;
case "minecraft:enchant_with_levels":
case "enchant_with_levels":
long maxEnchant = (long) ((JSONObject) ((JSONObject) function).get("levels")).get("max");
long minEnchant = (long) ((JSONObject) ((JSONObject) function).get("levels")).get("min");
JSONArray disabled = null;
if(((JSONObject) function).containsKey("disabled_enchants"))
disabled = (JSONArray) ((JSONObject) function).get("disabled_enchants");
functions.add(new EnchantFunction(FastMath.toIntExact(minEnchant), FastMath.toIntExact(maxEnchant), disabled, main));
break;
}
}
}
@@ -76,7 +86,7 @@ public class Entry {
*/
public ItemStack getItem(Random r) {
ItemStack item = main.getItemHandle().newItemStack(this.item, 1);
for(Function f : functions) {
for(LootFunction f : functions) {
item = f.apply(item, r);
}
return item;

View File

@@ -6,9 +6,9 @@ import com.dfsek.terra.api.platform.inventory.ItemStack;
import java.util.Random;
/**
* Loot Function fot setting the amount of an item.
* Loot LootFunction fot setting the amount of an item.
*/
public class AmountFunction implements Function {
public class AmountFunction implements LootFunction {
private final int max;
private final int min;

View File

@@ -7,9 +7,9 @@ import com.dfsek.terra.api.platform.inventory.item.ItemMeta;
import java.util.Random;
/**
* Loot Function for setting the damage on items in Loot Tables
* Loot LootFunction for setting the damage on items in Loot Tables
*/
public class DamageFunction implements Function {
public class DamageFunction implements LootFunction {
private final int max;
private final int min;

View File

@@ -0,0 +1,64 @@
package com.dfsek.terra.api.structures.loot.functions;
import com.dfsek.terra.api.platform.TerraPlugin;
import com.dfsek.terra.api.platform.inventory.ItemStack;
import com.dfsek.terra.api.platform.inventory.item.Enchantment;
import com.dfsek.terra.api.platform.inventory.item.ItemMeta;
import com.dfsek.terra.api.util.GlueList;
import net.jafama.FastMath;
import org.json.simple.JSONArray;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class EnchantFunction implements LootFunction {
private final int min;
private final int max;
private final JSONArray disabled;
private final TerraPlugin main;
public EnchantFunction(int min, int max, JSONArray disabled, TerraPlugin main) {
this.max = max;
this.min = min;
this.disabled = disabled;
this.main = main;
}
/**
* Applies the function to an ItemStack.
*
* @param original The ItemStack on which to apply the function.
* @param r The Random instance to use.
* @return - ItemStack - The mutated ItemStack.
*/
@Override
public ItemStack apply(ItemStack original, Random r) {
double enchant = (r.nextDouble() * (max - min)) + min;
List<Enchantment> possible = new GlueList<>();
for(Enchantment ench : main.getItemHandle().getEnchantments()) {
if(ench.canEnchantItem(original) && (disabled == null || !this.disabled.contains(ench.getID()))) {
possible.add(ench);
}
}
int numEnchant = (r.nextInt((int) FastMath.abs(enchant)) / 10 + 1);
Collections.shuffle(possible);
ItemMeta meta = original.getItemMeta();
iter:
for(int i = 0; i < numEnchant && i < possible.size(); i++) {
Enchantment chosen = possible.get(i);
for(Enchantment ench : meta.getEnchantments().keySet()) {
if(chosen.conflictsWith(ench)) continue iter;
}
int lvl = r.nextInt(1 + (int) (((enchant / 40 > 1) ? 1 : enchant / 40) * (chosen.getMaxLevel())));
try {
meta.addEnchantment(chosen, FastMath.max(lvl, 1));
} catch(IllegalArgumentException e) {
main.getLogger().warning("Attempted to enchant " + original.getType() + " with " + chosen + " at level " + FastMath.max(lvl, 1) + ", but an unexpected exception occurred! Usually this is caused by a misbehaving enchantment plugin.");
}
}
original.setItemMeta(meta);
return original;
}
}

View File

@@ -8,7 +8,7 @@ import java.util.Random;
/**
* Interface for mutating items in Loot Tables.
*/
public interface Function {
public interface LootFunction {
/**
* Applies the function to an ItemStack.
*