mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-29 03:59:06 +00:00
Added Object & Jigsaw Loot Tables
- Added the ability for placed objects and jigsaws to have select loot tables
- Includes the ability to filter loot tables based on block type/block state
- Overrides loot tables from the biome/region, but if no loot tables are provided for an object, they will still be used
- Uses weight based system for determining which table to pick (so it's guaranteed rather than by chance)
- Added WeightedRandom util class
- Fixed loot tables not being random based on the seed
- Fixed jigsaws breaking bedrock
- Fixed enchantments in loot tables not working for enchanted books
- Fixed mobs spawned in Jigsaws not being spawned in the center like they should be
This commit is contained in:
@@ -3,6 +3,7 @@ package com.volmit.iris.object;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import com.volmit.iris.util.Desc;
|
||||
@@ -52,6 +53,10 @@ public class IrisEnchantment
|
||||
{
|
||||
if(rng.nextDouble() < chance)
|
||||
{
|
||||
if (meta instanceof EnchantmentStorageMeta) {
|
||||
((EnchantmentStorageMeta) meta).addStoredEnchant(getEnchant(), getLevel(rng), true);
|
||||
return;
|
||||
}
|
||||
meta.addEnchant(getEnchant(), getLevel(rng), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -666,7 +666,12 @@ public class IrisObject extends IrisRegistrant
|
||||
for(BlockData k : j.getFind(rdata))
|
||||
{
|
||||
if (j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial())) {
|
||||
data = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata).clone();
|
||||
BlockData newData = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata).clone();
|
||||
|
||||
if (newData.getMaterial() == data.getMaterial())
|
||||
data = data.merge(newData);
|
||||
else
|
||||
data = newData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -726,7 +731,6 @@ public class IrisObject extends IrisRegistrant
|
||||
{
|
||||
placer.setTile(xx, yy, zz, tile);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
readLock.unlock();
|
||||
|
||||
72
src/main/java/com/volmit/iris/object/IrisObjectLoot.java
Normal file
72
src/main/java/com/volmit/iris/object/IrisObjectLoot.java
Normal file
@@ -0,0 +1,72 @@
|
||||
package com.volmit.iris.object;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.manager.IrisDataManager;
|
||||
import com.volmit.iris.scaffold.cache.AtomicCache;
|
||||
import com.volmit.iris.util.ArrayType;
|
||||
import com.volmit.iris.util.Desc;
|
||||
import com.volmit.iris.util.DontObfuscate;
|
||||
import com.volmit.iris.util.KList;
|
||||
import com.volmit.iris.util.RegistryListLoot;
|
||||
import com.volmit.iris.util.Required;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
@Accessors(chain = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Desc("Represents loot within this object or jigsaw piece")
|
||||
@Data
|
||||
public class IrisObjectLoot {
|
||||
|
||||
@DontObfuscate
|
||||
@ArrayType(min = 1, type = IrisBlockData.class)
|
||||
@Desc("The list of blocks this loot table should apply to")
|
||||
private KList<IrisBlockData> filter = new KList<>();
|
||||
|
||||
@Desc("Exactly match the block data or not")
|
||||
@DontObfuscate
|
||||
private boolean exact = false;
|
||||
|
||||
@DontObfuscate
|
||||
@Desc("The loot table name")
|
||||
@Required
|
||||
@RegistryListLoot
|
||||
private String name;
|
||||
|
||||
@DontObfuscate
|
||||
@Desc("The weight of this loot table being chosen")
|
||||
private int weight = 1;
|
||||
|
||||
private final transient AtomicCache<KList<BlockData>> filterCache = new AtomicCache<>();
|
||||
|
||||
public KList<BlockData> getFilter(IrisDataManager rdata)
|
||||
{
|
||||
return filterCache.aquire(() ->
|
||||
{
|
||||
KList<BlockData> b = new KList<>();
|
||||
|
||||
for(IrisBlockData i : filter)
|
||||
{
|
||||
BlockData bx = i.getBlockData(rdata);
|
||||
|
||||
if(bx != null)
|
||||
{
|
||||
b.add(bx);
|
||||
}
|
||||
}
|
||||
|
||||
return b;
|
||||
});
|
||||
}
|
||||
|
||||
public boolean matchesFilter(IrisDataManager manager, BlockData data) {
|
||||
for (BlockData filterData : getFilter(manager)) {
|
||||
if (filterData.matches(data)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.volmit.iris.object;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.generator.noise.CNG;
|
||||
import com.volmit.iris.manager.IrisDataManager;
|
||||
import com.volmit.iris.scaffold.cache.AtomicCache;
|
||||
import com.volmit.iris.scaffold.data.DataProvider;
|
||||
import com.volmit.iris.util.*;
|
||||
@@ -9,6 +11,8 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
@EqualsAndHashCode()
|
||||
@Accessors(chain = true)
|
||||
@@ -121,6 +125,11 @@ public class IrisObjectPlacement
|
||||
@Desc("Translate this object's placement")
|
||||
private IrisObjectTranslate translate = new IrisObjectTranslate();
|
||||
|
||||
@ArrayType(min = 1, type = IrisObjectLoot.class)
|
||||
@DontObfuscate
|
||||
@Desc("The loot tables to apply to these objects")
|
||||
private KList<IrisObjectLoot> loot = new KList<>();
|
||||
|
||||
public IrisObjectPlacement toPlacement(String... place)
|
||||
{
|
||||
IrisObjectPlacement p = new IrisObjectPlacement();
|
||||
@@ -145,6 +154,7 @@ public class IrisObjectPlacement
|
||||
p.setSnow(snow);
|
||||
p.setClamp(clamp);
|
||||
p.setRotation(rotation);
|
||||
p.setLoot(loot);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -191,4 +201,74 @@ public class IrisObjectPlacement
|
||||
public boolean isVacuum() {
|
||||
return getMode().equals(ObjectPlaceMode.VACUUM);
|
||||
}
|
||||
|
||||
private transient AtomicCache<TableCache> cache = new AtomicCache<>();
|
||||
|
||||
private class TableCache {
|
||||
transient WeightedRandom<IrisLootTable> global = new WeightedRandom<>();
|
||||
transient KMap<Material, WeightedRandom<IrisLootTable>> basic = new KMap<>();
|
||||
transient KMap<Material, KMap<BlockData, WeightedRandom<IrisLootTable>>> exact = new KMap<>();
|
||||
}
|
||||
|
||||
private TableCache getCache(IrisDataManager manager) {
|
||||
return cache.aquire(() -> {
|
||||
TableCache tc = new TableCache();
|
||||
|
||||
for (IrisObjectLoot loot : getLoot()) {
|
||||
IrisLootTable table = manager.getLootLoader().load(loot.getName());
|
||||
if (table == null) {
|
||||
Iris.warn("Couldn't find loot table " + loot.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (loot.getFilter().isEmpty()) //Table applies to all containers
|
||||
{
|
||||
tc.global.put(table, loot.getWeight());
|
||||
} else if (!loot.isExact()) //Table is meant to be by type
|
||||
{
|
||||
for (BlockData filterData : loot.getFilter(manager)) {
|
||||
if (!tc.basic.containsKey(filterData.getMaterial())) {
|
||||
tc.basic.put(filterData.getMaterial(), new WeightedRandom<>());
|
||||
}
|
||||
|
||||
tc.basic.get(filterData.getMaterial()).put(table, loot.getWeight());
|
||||
}
|
||||
} else //Filter is exact
|
||||
{
|
||||
for (BlockData filterData : loot.getFilter(manager)) {
|
||||
if (!tc.exact.containsKey(filterData.getMaterial())) {
|
||||
tc.exact.put(filterData.getMaterial(), new KMap<>());
|
||||
}
|
||||
|
||||
if (!tc.exact.get(filterData.getMaterial()).containsKey(filterData)) {
|
||||
tc.exact.get(filterData.getMaterial()).put(filterData, new WeightedRandom<>());
|
||||
}
|
||||
|
||||
tc.exact.get(filterData.getMaterial()).get(filterData).put(table, loot.getWeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
return tc;
|
||||
});
|
||||
}
|
||||
|
||||
public IrisLootTable getTable(BlockData data, IrisDataManager dataManager) {
|
||||
TableCache cache = getCache(dataManager);
|
||||
|
||||
if(B.isStorageChest(data))
|
||||
{
|
||||
IrisLootTable picked = null;
|
||||
if (cache.exact.containsKey(data.getMaterial()) && cache.exact.containsKey(data)) {
|
||||
picked = cache.exact.get(data.getMaterial()).get(data).pullRandom();
|
||||
} else if (cache.basic.containsKey(data.getMaterial())) {
|
||||
picked = cache.basic.get(data.getMaterial()).pullRandom();
|
||||
} else if (cache.global.getSize() > 0){
|
||||
picked = cache.global.pullRandom();
|
||||
}
|
||||
|
||||
return picked;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user