mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-04-05 07:16:10 +00:00
add enchantment to loot tables
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
*
|
||||
@@ -3,12 +3,30 @@ package com.dfsek.terra.bukkit.handles;
|
||||
import com.dfsek.terra.api.platform.block.MaterialData;
|
||||
import com.dfsek.terra.api.platform.handle.ItemHandle;
|
||||
import com.dfsek.terra.api.platform.inventory.ItemStack;
|
||||
import com.dfsek.terra.api.platform.inventory.item.Enchantment;
|
||||
import com.dfsek.terra.bukkit.util.MinecraftUtils;
|
||||
import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||
import com.dfsek.terra.bukkit.world.block.BukkitMaterialData;
|
||||
import com.dfsek.terra.bukkit.world.inventory.BukkitItemStack;
|
||||
import org.bukkit.NamespacedKey;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BukkitItemHandle implements ItemHandle {
|
||||
@Override
|
||||
public ItemStack newItemStack(MaterialData material, int amount) {
|
||||
return new BukkitItemStack(new org.bukkit.inventory.ItemStack(((BukkitMaterialData) material).getHandle(), amount));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enchantment getEnchantment(String id) {
|
||||
return BukkitAdapter.adapt(org.bukkit.enchantments.Enchantment.getByKey(NamespacedKey.minecraft(MinecraftUtils.stripMinecraftNamespace(id))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Enchantment> getEnchantments() {
|
||||
return Arrays.stream(org.bukkit.enchantments.Enchantment.values()).map(BukkitAdapter::adapt).collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.dfsek.terra.bukkit.util;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Vector3;
|
||||
import com.dfsek.terra.bukkit.world.BukkitWorld;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public final class BukkitConversions {
|
||||
public static Vector3 toTerraVector(Vector bukkit) {
|
||||
return new Vector3(bukkit.getX(), bukkit.getY(), bukkit.getZ());
|
||||
}
|
||||
|
||||
public static Location toBukkitLocation(com.dfsek.terra.api.math.vector.Location terra) {
|
||||
return new Location(((BukkitWorld) terra.getWorld()).getHandle(), terra.getX(), terra.getY(), terra.getZ());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.dfsek.terra.bukkit.util;
|
||||
|
||||
public final class MinecraftUtils {
|
||||
public static String stripMinecraftNamespace(String in) {
|
||||
if(in.startsWith("minecraft:")) return in.substring("minecraft:".length());
|
||||
return in;
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,11 @@ import com.dfsek.terra.api.platform.block.data.Rail;
|
||||
import com.dfsek.terra.api.platform.block.data.RedstoneWire;
|
||||
import com.dfsek.terra.api.platform.block.data.Slab;
|
||||
import com.dfsek.terra.api.platform.block.data.Stairs;
|
||||
import com.dfsek.terra.api.platform.inventory.item.Enchantment;
|
||||
import com.dfsek.terra.api.platform.world.Chunk;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.bukkit.BukkitCommandSender;
|
||||
import com.dfsek.terra.bukkit.world.inventory.meta.BukkitEnchantment;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@@ -338,4 +340,12 @@ public final class BukkitAdapter {
|
||||
public static org.bukkit.Chunk adapt(Chunk chunk) {
|
||||
return (org.bukkit.Chunk) chunk.getHandle();
|
||||
}
|
||||
|
||||
public static Enchantment adapt(org.bukkit.enchantments.Enchantment enchantment) {
|
||||
return new BukkitEnchantment(enchantment);
|
||||
}
|
||||
|
||||
public static org.bukkit.enchantments.Enchantment adapt(Enchantment enchantment) {
|
||||
return ((BukkitEnchantment) enchantment).getHandle();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
package com.dfsek.terra.bukkit.world.inventory;
|
||||
|
||||
import com.dfsek.terra.api.platform.inventory.item.Enchantment;
|
||||
import com.dfsek.terra.api.platform.inventory.item.ItemMeta;
|
||||
import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||
import com.dfsek.terra.bukkit.world.inventory.meta.BukkitDamageable;
|
||||
import com.dfsek.terra.bukkit.world.inventory.meta.BukkitEnchantment;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class BukkitItemMeta implements ItemMeta {
|
||||
private final org.bukkit.inventory.meta.ItemMeta delegate;
|
||||
|
||||
@@ -20,4 +26,16 @@ public class BukkitItemMeta implements ItemMeta {
|
||||
public org.bukkit.inventory.meta.ItemMeta getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Enchantment, Integer> getEnchantments() {
|
||||
Map<Enchantment, Integer> map = new HashMap<>();
|
||||
delegate.getEnchants().forEach((enchantment, integer) -> map.put(BukkitAdapter.adapt(enchantment), integer));
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEnchantment(Enchantment enchantment, int level) {
|
||||
delegate.addEnchant(((BukkitEnchantment) enchantment).getHandle(), level, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.dfsek.terra.bukkit.world.inventory.meta;
|
||||
|
||||
import com.dfsek.terra.api.platform.inventory.ItemStack;
|
||||
import com.dfsek.terra.api.platform.inventory.item.Enchantment;
|
||||
import com.dfsek.terra.bukkit.world.inventory.BukkitItemStack;
|
||||
|
||||
public class BukkitEnchantment implements Enchantment {
|
||||
private final org.bukkit.enchantments.Enchantment delegate;
|
||||
|
||||
public BukkitEnchantment(org.bukkit.enchantments.Enchantment delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.enchantments.Enchantment getHandle() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEnchantItem(ItemStack itemStack) {
|
||||
return delegate.canEnchantItem(((BukkitItemStack) itemStack).getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return delegate.getKey().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean conflictsWith(Enchantment other) {
|
||||
return delegate.conflictsWith(((BukkitEnchantment) other).getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxLevel() {
|
||||
return delegate.getMaxLevel();
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,16 @@ package com.dfsek.terra.fabric.inventory;
|
||||
import com.dfsek.terra.api.platform.block.MaterialData;
|
||||
import com.dfsek.terra.api.platform.handle.ItemHandle;
|
||||
import com.dfsek.terra.api.platform.inventory.ItemStack;
|
||||
import com.dfsek.terra.api.platform.inventory.item.Enchantment;
|
||||
|
||||
public class FabricItemHandle implements ItemHandle {
|
||||
@Override
|
||||
public ItemStack newItemStack(MaterialData material, int amount) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enchantment getEnchantment(String id) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user