Merge remote-tracking branch 'mcwg/v3.4.3' into v3.4.3

This commit is contained in:
RePixelatedMC
2024-09-30 08:19:46 +02:00
7 changed files with 213 additions and 54 deletions
@@ -62,10 +62,7 @@ import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch; import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import com.volmit.iris.util.stream.ProceduralStream; import com.volmit.iris.util.stream.ProceduralStream;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit; import org.bukkit.*;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
@@ -77,6 +74,7 @@ import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.awt.*; import java.awt.*;
import java.awt.Color;
import java.util.Arrays; import java.util.Arrays;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@@ -497,7 +495,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
} }
@Override @Override
default void addItems(boolean debug, Inventory inv, RNG rng, KList<IrisLootTable> tables, InventorySlotType slot, int x, int y, int z, int mgf) { default void addItems(boolean debug, Inventory inv, RNG rng, KList<IrisLootTable> tables, InventorySlotType slot, World world, int x, int y, int z, int mgf) {
KList<ItemStack> items = new KList<>(); KList<ItemStack> items = new KList<>();
int b = 4; int b = 4;
@@ -505,7 +503,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
if (i == null) if (i == null)
continue; continue;
b++; b++;
items.addAll(i.getLoot(debug, rng, slot, x, y, z)); items.addAll(i.getLoot(debug, rng, slot, world, x, y, z));
} }
if (PaperLib.isPaper() && getWorld().hasRealWorld()) { if (PaperLib.isPaper() && getWorld().hasRealWorld()) {
@@ -68,8 +68,7 @@ public class IrisLootEvent extends Event {
* allowing other plugins to modify or cancel the loot generation. * allowing other plugins to modify or cancel the loot generation.
*/ */
private Inventory triggerBukkitLootEvent() { private Inventory triggerBukkitLootEvent() {
if (block.getState() instanceof InventoryHolder) { if (block.getState() instanceof InventoryHolder holder) {
InventoryHolder holder = (InventoryHolder) block.getState();
Inventory inventory = holder.getInventory(); Inventory inventory = holder.getInventory();
inventory.clear(); inventory.clear();
@@ -78,11 +77,11 @@ public class IrisLootEvent extends Event {
int x = block.getX(), y = block.getY(), z = block.getZ(); int x = block.getX(), y = block.getY(), z = block.getZ();
for (IrisLootTable table : tables) for (IrisLootTable table : tables)
loot.addAll(table.getLoot(false, rng, slot, x, y, z)); loot.addAll(table.getLoot(false, rng, slot, block.getWorld(), x, y, z));
LootContext context = new LootContext.Builder(block.getLocation()).build(); LootContext context = new LootContext.Builder(block.getLocation()).build();
LootTable lootTable = Bukkit.getLootTable(LootTables.EMPTY.getKey()); // todo: Correct structure LootTable lootTable = LootTables.EMPTY.getLootTable(); // todo: Correct structure
LootGenerateEvent bukkitEvent = new LootGenerateEvent(engine.getWorld().realWorld(), null, holder, lootTable, context, loot, true); // todo: Use the iris loottable LootGenerateEvent bukkitEvent = new LootGenerateEvent(engine.getWorld().realWorld(), null, holder, lootTable, context, loot, true); // todo: Use the iris loottable
Bukkit.getServer().getPluginManager().callEvent(bukkitEvent); Bukkit.getServer().getPluginManager().callEvent(bukkitEvent);
@@ -271,7 +271,7 @@ public class IrisEntity extends IrisRegistrant {
for (String fi : getLoot().getTables()) { for (String fi : getLoot().getTables()) {
IrisLootTable i = gen.getData().getLootLoader().load(fi); IrisLootTable i = gen.getData().getLootLoader().load(fi);
items.addAll(i.getLoot(gen.isStudio(), rng.nextParallelRNG(345911), InventorySlotType.STORAGE, finalAt.getBlockX(), finalAt.getBlockY(), finalAt.getBlockZ())); items.addAll(i.getLoot(gen.isStudio(), rng.nextParallelRNG(345911), InventorySlotType.STORAGE, finalAt.getWorld(), finalAt.getBlockX(), finalAt.getBlockY(), finalAt.getBlockZ()));
} }
return items; return items;
@@ -33,6 +33,7 @@ import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@Accessors(chain = true) @Accessors(chain = true)
@@ -67,7 +68,7 @@ public class IrisLootTable extends IrisRegistrant {
@ArrayType(min = 1, type = IrisLoot.class) @ArrayType(min = 1, type = IrisLoot.class)
private KList<IrisLoot> loot = new KList<>(); private KList<IrisLoot> loot = new KList<>();
public KList<ItemStack> getLoot(boolean debug, RNG rng, InventorySlotType slot, int x, int y, int z) { public KList<ItemStack> getLoot(boolean debug, RNG rng, InventorySlotType slot, World world, int x, int y, int z) {
KList<ItemStack> lootf = new KList<>(); KList<ItemStack> lootf = new KList<>();
int m = 0; int m = 0;
@@ -34,9 +34,15 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.TreeType; import org.bukkit.TreeType;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.loot.LootTable;
import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
@Snippet("object-placer") @Snippet("object-placer")
@EqualsAndHashCode() @EqualsAndHashCode()
@@ -123,6 +129,8 @@ 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<>();
@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.") @Desc("Whether the given loot tables override any and all other loot tables available in the dimension, region or biome.")
private boolean overrideGlobalLoot = false; private boolean overrideGlobalLoot = false;
@Desc("This object / these objects override the following trees when they grow...") @Desc("This object / these objects override the following trees when they grow...")
@@ -138,7 +146,8 @@ 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> cache = new AtomicCache<>(); private transient AtomicCache<TableCache<IrisLootTable>> 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();
@@ -209,14 +218,21 @@ 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 getCache(IrisData manager) { private TableCache<IrisLootTable> getCache(IrisData manager) {
return cache.aquire(() -> { return cache.aquire(() -> getCache(manager, manager.getLootLoader()::load));
TableCache tc = new TableCache(); }
private TableCache<IrisVanillaLootTable> getVanillaCache(IrisData manager) {
return vanillaCache.aquire(() -> getCache(manager, IrisObjectPlacement::getVanillaTable));
}
private <T> TableCache<T> getCache(IrisData manager, Function<String, T> loader) {
TableCache<T> tc = new TableCache<>();
for (IrisObjectLoot loot : getLoot()) { for (IrisObjectLoot loot : getLoot()) {
if (loot == null) if (loot == null)
continue; continue;
IrisLootTable table = manager.getLootLoader().load(loot.getName()); T 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;
@@ -250,7 +266,14 @@ public class IrisObjectPlacement {
} }
} }
return tc; return tc;
}); }
@Nullable
private static IrisVanillaLootTable getVanillaTable(String name) {
NamespacedKey key = NamespacedKey.fromString(name);
if (key == null)
return null;
return new IrisVanillaLootTable(Bukkit.getLootTable(key));
} }
/** /**
@@ -261,10 +284,16 @@ 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) {
TableCache cache = getCache(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) {
if (B.isStorageChest(data)) { if (B.isStorageChest(data)) {
IrisLootTable picked = null; T 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())) {
@@ -279,9 +308,9 @@ public class IrisObjectPlacement {
return null; return null;
} }
private static class TableCache { private static class TableCache<T> {
final transient WeightedRandom<IrisLootTable> global = new WeightedRandom<>(); final transient WeightedRandom<T> global = new WeightedRandom<>();
final transient KMap<Material, WeightedRandom<IrisLootTable>> basic = new KMap<>(); final transient KMap<Material, WeightedRandom<T>> basic = new KMap<>();
final transient KMap<Material, KMap<BlockData, WeightedRandom<IrisLootTable>>> exact = new KMap<>(); final transient KMap<Material, KMap<BlockData, WeightedRandom<T>>> exact = new KMap<>();
} }
} }
@@ -0,0 +1,48 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.collection.KList;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.bukkit.block.data.BlockData;
@Snippet("object-vanilla-loot")
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("Represents vanilla loot within this object or jigsaw piece")
@Data
public class IrisObjectVanillaLoot {
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")
private KList<IrisBlockData> filter = new KList<>();
@Desc("Exactly match the block data or not")
private boolean exact = false;
@Desc("The vanilla loot table key")
@Required
private String name;
@Desc("The weight of this loot table being chosen")
private int weight = 1;
public KList<BlockData> getFilter(IrisData 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;
});
}
}
@@ -0,0 +1,84 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.math.RNG;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import org.bukkit.loot.LootContext;
import org.bukkit.loot.LootTable;
import java.io.File;
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisVanillaLootTable extends IrisLootTable {
private final LootTable lootTable;
public KList<ItemStack> getLoot(RNG rng, World world, int x, int y, int z) {
return new KList<>(lootTable.populateLoot(rng, new LootContext.Builder(new Location(world, x, y, z)).build()));
}
@Override
public String getName() {
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
}
@Override
public int getRarity() {
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
}
@Override
public int getMaxPicked() {
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
}
@Override
public int getMinPicked() {
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
}
@Override
public int getMaxTries() {
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
}
@Override
public KList<IrisLoot> getLoot() {
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
}
@Override
public KList<ItemStack> getLoot(boolean debug, RNG rng, InventorySlotType slot, World world, int x, int y, int z) {
return new KList<>(lootTable.populateLoot(rng, new LootContext.Builder(new Location(world, x, y, z)).build()));
}
@Override
public String getFolderName() {
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
}
@Override
public String getTypeName() {
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
}
@Override
public File getLoadFile() {
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
}
@Override
public IrisData getLoader() {
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
}
@Override
public KList<String> getPreprocessors() {
throw new IllegalStateException("Vanilla loot tables should not be used in Iris");
}
}