mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-02 07:56:48 +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())
|
if (!Bukkit.isPrimaryThread())
|
||||||
J.sfut(() -> Bukkit.getPluginManager().callEvent(event)).join();
|
J.sfut(() -> Bukkit.getPluginManager().callEvent(event)).join();
|
||||||
else Bukkit.getPluginManager().callEvent(event);
|
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
|
@AllArgsConstructor
|
||||||
@Desc("Represents loot within this object or jigsaw piece")
|
@Desc("Represents loot within this object or jigsaw piece")
|
||||||
@Data
|
@Data
|
||||||
public class IrisObjectLoot {
|
public class IrisObjectLoot implements IObjectLoot {
|
||||||
private final transient AtomicCache<KList<BlockData>> filterCache = new AtomicCache<>();
|
private final transient AtomicCache<KList<BlockData>> filterCache = new AtomicCache<>();
|
||||||
@ArrayType(min = 1, type = IrisBlockData.class)
|
@ArrayType(min = 1, type = IrisBlockData.class)
|
||||||
@Desc("The list of blocks this loot table should apply to")
|
@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.bukkit.block.data.BlockData;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
@Snippet("object-placer")
|
@Snippet("object-placer")
|
||||||
@ -130,6 +131,7 @@ public class IrisObjectPlacement {
|
|||||||
@ArrayType(min = 1, type = IrisObjectLoot.class)
|
@ArrayType(min = 1, type = IrisObjectLoot.class)
|
||||||
@Desc("The loot tables to apply to these objects")
|
@Desc("The loot tables to apply to these objects")
|
||||||
private KList<IrisObjectLoot> loot = new KList<>();
|
private KList<IrisObjectLoot> loot = new KList<>();
|
||||||
|
@ArrayType(min = 1, type = IrisObjectVanillaLoot.class)
|
||||||
@Desc("The vanilla loot tables to apply to these objects")
|
@Desc("The vanilla loot tables to apply to these objects")
|
||||||
private KList<IrisObjectVanillaLoot> vanillaLoot = new KList<>();
|
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.")
|
@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<>();
|
private KList<String> forbiddenCollisions = new KList<>();
|
||||||
@Desc("Ignore any placement restrictions for this object")
|
@Desc("Ignore any placement restrictions for this object")
|
||||||
private boolean forcePlace = false;
|
private boolean forcePlace = false;
|
||||||
private transient AtomicCache<TableCache<IrisLootTable>> cache = new AtomicCache<>();
|
private transient AtomicCache<TableCache> cache = new AtomicCache<>();
|
||||||
private transient AtomicCache<TableCache<IrisVanillaLootTable>> vanillaCache = new AtomicCache<>();
|
|
||||||
|
|
||||||
public IrisObjectPlacement toPlacement(String... place) {
|
public IrisObjectPlacement toPlacement(String... place) {
|
||||||
IrisObjectPlacement p = new IrisObjectPlacement();
|
IrisObjectPlacement p = new IrisObjectPlacement();
|
||||||
@ -219,21 +220,24 @@ public class IrisObjectPlacement {
|
|||||||
return (int) Math.round(densityStyle.get(rng, x, z, data));
|
return (int) Math.round(densityStyle.get(rng, x, z, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
private TableCache<IrisLootTable> getCache(IrisData manager) {
|
private TableCache getCache(IrisData manager) {
|
||||||
return cache.aquire(() -> getCache(manager, manager.getLootLoader()::load));
|
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) {
|
private TableCache getCache(IrisData manager, KList<? extends IObjectLoot> list, Function<String, IrisLootTable> loader) {
|
||||||
return vanillaCache.aquire(() -> getCache(manager, IrisObjectPlacement::getVanillaTable));
|
TableCache tc = new TableCache();
|
||||||
}
|
|
||||||
|
|
||||||
private <T> TableCache<T> getCache(IrisData manager, Function<String, T> loader) {
|
for (IObjectLoot loot : list) {
|
||||||
TableCache<T> tc = new TableCache<>();
|
|
||||||
|
|
||||||
for (IrisObjectLoot loot : getLoot()) {
|
|
||||||
if (loot == null)
|
if (loot == null)
|
||||||
continue;
|
continue;
|
||||||
T table = loader.apply(loot.getName());
|
IrisLootTable table = loader.apply(loot.getName());
|
||||||
if (table == null) {
|
if (table == null) {
|
||||||
Iris.warn("Couldn't find loot table " + loot.getName());
|
Iris.warn("Couldn't find loot table " + loot.getName());
|
||||||
continue;
|
continue;
|
||||||
@ -271,10 +275,10 @@ public class IrisObjectPlacement {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static IrisVanillaLootTable getVanillaTable(String name) {
|
private static IrisVanillaLootTable getVanillaTable(String name) {
|
||||||
NamespacedKey key = NamespacedKey.fromString(name);
|
return Optional.ofNullable(NamespacedKey.fromString(name))
|
||||||
if (key == null)
|
.map(Bukkit::getLootTable)
|
||||||
return null;
|
.map(IrisVanillaLootTable::new)
|
||||||
return new IrisVanillaLootTable(Bukkit.getLootTable(key));
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -285,16 +289,9 @@ public class IrisObjectPlacement {
|
|||||||
* @return The loot table it should use.
|
* @return The loot table it should use.
|
||||||
*/
|
*/
|
||||||
public IrisLootTable getTable(BlockData data, IrisData dataManager) {
|
public IrisLootTable getTable(BlockData data, IrisData dataManager) {
|
||||||
IrisLootTable table = pickTable(data, getVanillaCache(dataManager));
|
TableCache cache = getCache(dataManager);
|
||||||
if (table == null) {
|
|
||||||
table = pickTable(data, getCache(dataManager));
|
|
||||||
}
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> T pickTable(BlockData data, TableCache<T> cache) {
|
|
||||||
if (B.isStorageChest(data)) {
|
if (B.isStorageChest(data)) {
|
||||||
T picked = null;
|
IrisLootTable picked = null;
|
||||||
if (cache.exact.containsKey(data.getMaterial()) && cache.exact.get(data.getMaterial()).containsKey(data)) {
|
if (cache.exact.containsKey(data.getMaterial()) && cache.exact.get(data.getMaterial()).containsKey(data)) {
|
||||||
picked = cache.exact.get(data.getMaterial()).get(data).pullRandom();
|
picked = cache.exact.get(data.getMaterial()).get(data).pullRandom();
|
||||||
} else if (cache.basic.containsKey(data.getMaterial())) {
|
} else if (cache.basic.containsKey(data.getMaterial())) {
|
||||||
@ -309,9 +306,15 @@ public class IrisObjectPlacement {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TableCache<T> {
|
private static class TableCache {
|
||||||
final transient WeightedRandom<T> global = new WeightedRandom<>();
|
final transient WeightedRandom<IrisLootTable> global = new WeightedRandom<>();
|
||||||
final transient KMap<Material, WeightedRandom<T>> basic = new KMap<>();
|
final transient KMap<Material, WeightedRandom<IrisLootTable>> basic = new KMap<>();
|
||||||
final transient KMap<Material, KMap<BlockData, WeightedRandom<T>>> exact = 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
|
@AllArgsConstructor
|
||||||
@Desc("Represents vanilla loot within this object or jigsaw piece")
|
@Desc("Represents vanilla loot within this object or jigsaw piece")
|
||||||
@Data
|
@Data
|
||||||
public class IrisObjectVanillaLoot {
|
public class IrisObjectVanillaLoot implements IObjectLoot {
|
||||||
private final transient AtomicCache<KList<BlockData>> filterCache = new AtomicCache<>();
|
private final transient AtomicCache<KList<BlockData>> filterCache = new AtomicCache<>();
|
||||||
@ArrayType(min = 1, type = IrisBlockData.class)
|
@ArrayType(min = 1, type = IrisBlockData.class)
|
||||||
@Desc("The list of blocks this loot table should apply to")
|
@Desc("The list of blocks this loot table should apply to")
|
||||||
|
@ -20,32 +20,32 @@ public class IrisVanillaLootTable extends IrisLootTable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
return "Vanilla " + lootTable.getKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRarity() {
|
public int getRarity() {
|
||||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxPicked() {
|
public int getMaxPicked() {
|
||||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinPicked() {
|
public int getMinPicked() {
|
||||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxTries() {
|
public int getMaxTries() {
|
||||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KList<IrisLoot> getLoot() {
|
public KList<IrisLoot> getLoot() {
|
||||||
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
|
return new KList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -55,26 +55,26 @@ public class IrisVanillaLootTable extends IrisLootTable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFolderName() {
|
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
|
@Override
|
||||||
public String getTypeName() {
|
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
|
@Override
|
||||||
public File getLoadFile() {
|
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
|
@Override
|
||||||
public IrisData getLoader() {
|
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
|
@Override
|
||||||
public KList<String> getPreprocessors() {
|
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.Enumeration;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
@SuppressWarnings("ALL")
|
@SuppressWarnings("ALL")
|
||||||
public class KMap<K, V> extends ConcurrentHashMap<K, V> {
|
public class KMap<K, V> extends ConcurrentHashMap<K, V> {
|
||||||
@ -151,6 +152,17 @@ public class KMap<K, V> extends ConcurrentHashMap<K, V> {
|
|||||||
return this;
|
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
|
* 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);
|
var b = w.getBlockAt((chunk.getX() << 4) + rX, y, (chunk.getZ() << 4) + rZ);
|
||||||
if (++y >= maxY) {
|
if (++y > maxY) {
|
||||||
y = minY;
|
y = minY;
|
||||||
if (++rX > mX) {
|
if (++rX > mX) {
|
||||||
if (++rZ > mZ) {
|
if (++rZ > mZ) {
|
||||||
|
@ -42,11 +42,18 @@ public class WeightedRandom<T> {
|
|||||||
totalWeight += weight;
|
totalWeight += weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WeightedRandom<T> merge(WeightedRandom<T> other) {
|
||||||
|
weightedObjects.addAll(other.weightedObjects);
|
||||||
|
totalWeight += other.totalWeight;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public T pullRandom() {
|
public T pullRandom() {
|
||||||
int pull = random.nextInt(totalWeight);
|
int pull = random.nextInt(totalWeight);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
while (pull > 0) {
|
while (pull > 0) {
|
||||||
pull -= weightedObjects.get(index).getV();
|
pull -= weightedObjects.get(index).getV();
|
||||||
|
if (pull <= 0) break;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
return weightedObjects.get(index).getK();
|
return weightedObjects.get(index).getK();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user