mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-01 23:47:21 +00:00
fix vanilla loottables not applying
This commit is contained in:
parent
d192e2b6d1
commit
5c26ec2521
@ -104,6 +104,6 @@ public class IrisLootEvent extends Event {
|
||||
if (!Bukkit.isPrimaryThread())
|
||||
J.sfut(() -> Bukkit.getPluginManager().callEvent(event)).join();
|
||||
else Bukkit.getPluginManager().callEvent(event);
|
||||
return !event.isCancelled();
|
||||
return event.isCancelled();
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.volmit.iris.engine.object;
|
||||
|
||||
import com.volmit.iris.core.loader.IrisData;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
public interface IObjectLoot {
|
||||
KList<IrisBlockData> getFilter();
|
||||
KList<BlockData> getFilter(IrisData manager);
|
||||
boolean isExact();
|
||||
String getName();
|
||||
int getWeight();
|
||||
}
|
@ -34,7 +34,7 @@ import org.bukkit.block.data.BlockData;
|
||||
@AllArgsConstructor
|
||||
@Desc("Represents loot within this object or jigsaw piece")
|
||||
@Data
|
||||
public class IrisObjectLoot {
|
||||
public class IrisObjectLoot implements IObjectLoot {
|
||||
private final transient AtomicCache<KList<BlockData>> filterCache = new AtomicCache<>();
|
||||
@ArrayType(min = 1, type = IrisBlockData.class)
|
||||
@Desc("The list of blocks this loot table should apply to")
|
||||
|
@ -41,6 +41,7 @@ import org.bukkit.TreeType;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Snippet("object-placer")
|
||||
@ -130,6 +131,7 @@ public class IrisObjectPlacement {
|
||||
@ArrayType(min = 1, type = IrisObjectLoot.class)
|
||||
@Desc("The loot tables to apply to these objects")
|
||||
private KList<IrisObjectLoot> loot = new KList<>();
|
||||
@ArrayType(min = 1, type = IrisObjectVanillaLoot.class)
|
||||
@Desc("The vanilla loot tables to apply to these objects")
|
||||
private KList<IrisObjectVanillaLoot> vanillaLoot = new KList<>();
|
||||
@Desc("Whether the given loot tables override any and all other loot tables available in the dimension, region or biome.")
|
||||
@ -147,8 +149,7 @@ public class IrisObjectPlacement {
|
||||
private KList<String> forbiddenCollisions = new KList<>();
|
||||
@Desc("Ignore any placement restrictions for this object")
|
||||
private boolean forcePlace = false;
|
||||
private transient AtomicCache<TableCache<IrisLootTable>> cache = new AtomicCache<>();
|
||||
private transient AtomicCache<TableCache<IrisVanillaLootTable>> vanillaCache = new AtomicCache<>();
|
||||
private transient AtomicCache<TableCache> cache = new AtomicCache<>();
|
||||
|
||||
public IrisObjectPlacement toPlacement(String... place) {
|
||||
IrisObjectPlacement p = new IrisObjectPlacement();
|
||||
@ -219,21 +220,24 @@ public class IrisObjectPlacement {
|
||||
return (int) Math.round(densityStyle.get(rng, x, z, data));
|
||||
}
|
||||
|
||||
private TableCache<IrisLootTable> getCache(IrisData manager) {
|
||||
return cache.aquire(() -> getCache(manager, manager.getLootLoader()::load));
|
||||
private TableCache getCache(IrisData manager) {
|
||||
return cache.aquire(() -> {
|
||||
TableCache cache = new TableCache();
|
||||
|
||||
cache.merge(getCache(manager, getVanillaLoot(), IrisObjectPlacement::getVanillaTable));
|
||||
cache.merge(getCache(manager, getLoot(), manager.getLootLoader()::load));
|
||||
|
||||
return cache;
|
||||
});
|
||||
}
|
||||
|
||||
private TableCache<IrisVanillaLootTable> getVanillaCache(IrisData manager) {
|
||||
return vanillaCache.aquire(() -> getCache(manager, IrisObjectPlacement::getVanillaTable));
|
||||
}
|
||||
private TableCache getCache(IrisData manager, KList<? extends IObjectLoot> list, Function<String, IrisLootTable> loader) {
|
||||
TableCache tc = new TableCache();
|
||||
|
||||
private <T> TableCache<T> getCache(IrisData manager, Function<String, T> loader) {
|
||||
TableCache<T> tc = new TableCache<>();
|
||||
|
||||
for (IrisObjectLoot loot : getLoot()) {
|
||||
for (IObjectLoot loot : list) {
|
||||
if (loot == null)
|
||||
continue;
|
||||
T table = loader.apply(loot.getName());
|
||||
IrisLootTable table = loader.apply(loot.getName());
|
||||
if (table == null) {
|
||||
Iris.warn("Couldn't find loot table " + loot.getName());
|
||||
continue;
|
||||
@ -271,10 +275,10 @@ public class IrisObjectPlacement {
|
||||
|
||||
@Nullable
|
||||
private static IrisVanillaLootTable getVanillaTable(String name) {
|
||||
NamespacedKey key = NamespacedKey.fromString(name);
|
||||
if (key == null)
|
||||
return null;
|
||||
return new IrisVanillaLootTable(Bukkit.getLootTable(key));
|
||||
return Optional.ofNullable(NamespacedKey.fromString(name))
|
||||
.map(Bukkit::getLootTable)
|
||||
.map(IrisVanillaLootTable::new)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -285,16 +289,9 @@ public class IrisObjectPlacement {
|
||||
* @return The loot table it should use.
|
||||
*/
|
||||
public IrisLootTable getTable(BlockData data, IrisData dataManager) {
|
||||
IrisLootTable table = pickTable(data, getVanillaCache(dataManager));
|
||||
if (table == null) {
|
||||
table = pickTable(data, getCache(dataManager));
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
private <T> T pickTable(BlockData data, TableCache<T> cache) {
|
||||
TableCache cache = getCache(dataManager);
|
||||
if (B.isStorageChest(data)) {
|
||||
T picked = null;
|
||||
IrisLootTable picked = null;
|
||||
if (cache.exact.containsKey(data.getMaterial()) && cache.exact.get(data.getMaterial()).containsKey(data)) {
|
||||
picked = cache.exact.get(data.getMaterial()).get(data).pullRandom();
|
||||
} else if (cache.basic.containsKey(data.getMaterial())) {
|
||||
@ -309,9 +306,15 @@ public class IrisObjectPlacement {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class TableCache<T> {
|
||||
final transient WeightedRandom<T> global = new WeightedRandom<>();
|
||||
final transient KMap<Material, WeightedRandom<T>> basic = new KMap<>();
|
||||
final transient KMap<Material, KMap<BlockData, WeightedRandom<T>>> exact = new KMap<>();
|
||||
private static class TableCache {
|
||||
final transient WeightedRandom<IrisLootTable> global = new WeightedRandom<>();
|
||||
final transient KMap<Material, WeightedRandom<IrisLootTable>> basic = new KMap<>();
|
||||
final transient KMap<Material, KMap<BlockData, WeightedRandom<IrisLootTable>>> exact = new KMap<>();
|
||||
|
||||
private void merge(TableCache other) {
|
||||
global.merge(other.global);
|
||||
basic.merge(other.basic, WeightedRandom::merge);
|
||||
exact.merge(other.exact, (a, b) -> a.merge(b, WeightedRandom::merge));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import org.bukkit.block.data.BlockData;
|
||||
@AllArgsConstructor
|
||||
@Desc("Represents vanilla loot within this object or jigsaw piece")
|
||||
@Data
|
||||
public class IrisObjectVanillaLoot {
|
||||
public class IrisObjectVanillaLoot implements IObjectLoot {
|
||||
private final transient AtomicCache<KList<BlockData>> filterCache = new AtomicCache<>();
|
||||
@ArrayType(min = 1, type = IrisBlockData.class)
|
||||
@Desc("The list of blocks this loot table should apply to")
|
||||
|
@ -20,32 +20,32 @@ public class IrisVanillaLootTable extends IrisLootTable {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
||||
return "Vanilla " + lootTable.getKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRarity() {
|
||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxPicked() {
|
||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinPicked() {
|
||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxTries() {
|
||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KList<IrisLoot> getLoot() {
|
||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
||||
return new KList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -55,26 +55,26 @@ public class IrisVanillaLootTable extends IrisLootTable {
|
||||
|
||||
@Override
|
||||
public String getFolderName() {
|
||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
||||
throw new UnsupportedOperationException("VanillaLootTables do not have a folder name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
||||
throw new UnsupportedOperationException("VanillaLootTables do not have a type name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getLoadFile() {
|
||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
||||
throw new UnsupportedOperationException("VanillaLootTables do not have a load file");
|
||||
}
|
||||
|
||||
@Override
|
||||
public IrisData getLoader() {
|
||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
||||
throw new UnsupportedOperationException("VanillaLootTables do not have a loader");
|
||||
}
|
||||
|
||||
@Override
|
||||
public KList<String> getPreprocessors() {
|
||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
||||
return new KList<>();
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import java.util.Comparator;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
public class KMap<K, V> extends ConcurrentHashMap<K, V> {
|
||||
@ -151,6 +152,17 @@ public class KMap<K, V> extends ConcurrentHashMap<K, V> {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge with another map
|
||||
*
|
||||
* @param m the map to merge
|
||||
* @return this map (builder)
|
||||
*/
|
||||
public KMap<K, V> merge(KMap<K, V> m, BiFunction<V, V, V> merger) {
|
||||
m.forEach((k, v) -> merge(k, v, merger));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a copy of this map
|
||||
*
|
||||
|
@ -810,7 +810,7 @@ public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializ
|
||||
}
|
||||
|
||||
var b = w.getBlockAt((chunk.getX() << 4) + rX, y, (chunk.getZ() << 4) + rZ);
|
||||
if (++y >= maxY) {
|
||||
if (++y > maxY) {
|
||||
y = minY;
|
||||
if (++rX > mX) {
|
||||
if (++rZ > mZ) {
|
||||
|
@ -42,11 +42,18 @@ public class WeightedRandom<T> {
|
||||
totalWeight += weight;
|
||||
}
|
||||
|
||||
public WeightedRandom<T> merge(WeightedRandom<T> other) {
|
||||
weightedObjects.addAll(other.weightedObjects);
|
||||
totalWeight += other.totalWeight;
|
||||
return this;
|
||||
}
|
||||
|
||||
public T pullRandom() {
|
||||
int pull = random.nextInt(totalWeight);
|
||||
int index = 0;
|
||||
while (pull > 0) {
|
||||
pull -= weightedObjects.get(index).getV();
|
||||
if (pull <= 0) break;
|
||||
index++;
|
||||
}
|
||||
return weightedObjects.get(index).getK();
|
||||
|
Loading…
x
Reference in New Issue
Block a user