From 5c26ec2521887509ad02868ebe126aba5abc93e3 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Sat, 28 Dec 2024 00:43:01 +0100 Subject: [PATCH] fix vanilla loottables not applying --- .../iris/engine/framework/IrisLootEvent.java | 2 +- .../iris/engine/object/IObjectLoot.java | 13 ++++ .../iris/engine/object/IrisObjectLoot.java | 2 +- .../engine/object/IrisObjectPlacement.java | 61 ++++++++++--------- .../engine/object/IrisObjectVanillaLoot.java | 2 +- .../engine/object/IrisVanillaLootTable.java | 22 +++---- .../com/volmit/iris/util/collection/KMap.java | 12 ++++ .../com/volmit/iris/util/data/Cuboid.java | 2 +- .../volmit/iris/util/data/WeightedRandom.java | 7 +++ 9 files changed, 79 insertions(+), 44 deletions(-) create mode 100644 core/src/main/java/com/volmit/iris/engine/object/IObjectLoot.java diff --git a/core/src/main/java/com/volmit/iris/engine/framework/IrisLootEvent.java b/core/src/main/java/com/volmit/iris/engine/framework/IrisLootEvent.java index aa66a12d9..2ade7332f 100644 --- a/core/src/main/java/com/volmit/iris/engine/framework/IrisLootEvent.java +++ b/core/src/main/java/com/volmit/iris/engine/framework/IrisLootEvent.java @@ -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(); } } \ No newline at end of file diff --git a/core/src/main/java/com/volmit/iris/engine/object/IObjectLoot.java b/core/src/main/java/com/volmit/iris/engine/object/IObjectLoot.java new file mode 100644 index 000000000..6ee2ec882 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/engine/object/IObjectLoot.java @@ -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 getFilter(); + KList getFilter(IrisData manager); + boolean isExact(); + String getName(); + int getWeight(); +} diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObjectLoot.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObjectLoot.java index eb3781a4d..da09ae2fc 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObjectLoot.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObjectLoot.java @@ -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> filterCache = new AtomicCache<>(); @ArrayType(min = 1, type = IrisBlockData.class) @Desc("The list of blocks this loot table should apply to") diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java index 5d0e95a40..adab09743 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java @@ -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 loot = new KList<>(); + @ArrayType(min = 1, type = IrisObjectVanillaLoot.class) @Desc("The vanilla loot tables to apply to these objects") private KList 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 forbiddenCollisions = new KList<>(); @Desc("Ignore any placement restrictions for this object") private boolean forcePlace = false; - private transient AtomicCache> cache = new AtomicCache<>(); - private transient AtomicCache> vanillaCache = new AtomicCache<>(); + private transient AtomicCache 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 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 getVanillaCache(IrisData manager) { - return vanillaCache.aquire(() -> getCache(manager, IrisObjectPlacement::getVanillaTable)); - } + private TableCache getCache(IrisData manager, KList list, Function loader) { + TableCache tc = new TableCache(); - private TableCache getCache(IrisData manager, Function loader) { - TableCache 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 pickTable(BlockData data, TableCache 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 { - final transient WeightedRandom global = new WeightedRandom<>(); - final transient KMap> basic = new KMap<>(); - final transient KMap>> exact = new KMap<>(); + private static class TableCache { + final transient WeightedRandom global = new WeightedRandom<>(); + final transient KMap> basic = new KMap<>(); + final transient KMap>> 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)); + } } } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObjectVanillaLoot.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObjectVanillaLoot.java index b3f9ebc4b..bd93ea998 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObjectVanillaLoot.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObjectVanillaLoot.java @@ -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> filterCache = new AtomicCache<>(); @ArrayType(min = 1, type = IrisBlockData.class) @Desc("The list of blocks this loot table should apply to") diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisVanillaLootTable.java b/core/src/main/java/com/volmit/iris/engine/object/IrisVanillaLootTable.java index 36bf628ee..ee25d447b 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisVanillaLootTable.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisVanillaLootTable.java @@ -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 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 getPreprocessors() { - throw new IllegalStateException("Vanilla loot tables should not be used in Iris"); + return new KList<>(); } } diff --git a/core/src/main/java/com/volmit/iris/util/collection/KMap.java b/core/src/main/java/com/volmit/iris/util/collection/KMap.java index 06fc14568..01baab32b 100644 --- a/core/src/main/java/com/volmit/iris/util/collection/KMap.java +++ b/core/src/main/java/com/volmit/iris/util/collection/KMap.java @@ -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 extends ConcurrentHashMap { @@ -151,6 +152,17 @@ public class KMap extends ConcurrentHashMap { return this; } + /** + * Merge with another map + * + * @param m the map to merge + * @return this map (builder) + */ + public KMap merge(KMap m, BiFunction merger) { + m.forEach((k, v) -> merge(k, v, merger)); + return this; + } + /** * Return a copy of this map * diff --git a/core/src/main/java/com/volmit/iris/util/data/Cuboid.java b/core/src/main/java/com/volmit/iris/util/data/Cuboid.java index c2ea5b51a..ccd837eb2 100644 --- a/core/src/main/java/com/volmit/iris/util/data/Cuboid.java +++ b/core/src/main/java/com/volmit/iris/util/data/Cuboid.java @@ -810,7 +810,7 @@ public class Cuboid implements Iterable, 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) { diff --git a/core/src/main/java/com/volmit/iris/util/data/WeightedRandom.java b/core/src/main/java/com/volmit/iris/util/data/WeightedRandom.java index 16cdd6b4e..ba6cf07a6 100644 --- a/core/src/main/java/com/volmit/iris/util/data/WeightedRandom.java +++ b/core/src/main/java/com/volmit/iris/util/data/WeightedRandom.java @@ -42,11 +42,18 @@ public class WeightedRandom { totalWeight += weight; } + public WeightedRandom merge(WeightedRandom 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();