From 29526a80a981a2e58191a1add69c9f02f126fa60 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Tue, 25 Jun 2024 13:35:34 +0200 Subject: [PATCH] improve custom block/item api to allow custom settings --- .../iris/core/link/EcoItemsDataProvider.java | 5 +- .../link/ExecutableItemsDataProvider.java | 5 +- .../iris/core/link/ExternalDataProvider.java | 16 ++++- .../iris/core/link/HMCLeavesDataProvider.java | 10 ++- .../iris/core/link/ItemAdderDataProvider.java | 5 +- .../iris/core/link/MMOItemsDataProvider.java | 28 +++++++- .../iris/core/link/OraxenDataProvider.java | 69 +++++++++++++++++-- .../iris/core/nms/v1X/NMSBinding1X.java | 8 +++ .../iris/core/service/ExternalDataSVC.java | 42 +++++++++-- .../volmit/iris/engine/object/IrisLoot.java | 3 +- 10 files changed, 163 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/link/EcoItemsDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/EcoItemsDataProvider.java index 615256e66..d42684e7e 100644 --- a/core/src/main/java/com/volmit/iris/core/link/EcoItemsDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/EcoItemsDataProvider.java @@ -2,6 +2,7 @@ package com.volmit.iris.core.link; import com.volmit.iris.Iris; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.reflect.WrappedField; import com.willfp.ecoitems.items.EcoItem; import com.willfp.ecoitems.items.EcoItems; @@ -33,12 +34,12 @@ public class EcoItemsDataProvider extends ExternalDataProvider { } @Override - public BlockData getBlockData(Identifier blockId) throws MissingResourceException { + public BlockData getBlockData(Identifier blockId, KMap state) throws MissingResourceException { throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key()); } @Override - public ItemStack getItemStack(Identifier itemId) throws MissingResourceException { + public ItemStack getItemStack(Identifier itemId, KMap customNbt) throws MissingResourceException { EcoItem item = EcoItems.INSTANCE.getByID(itemId.key()); if (item == null) throw new MissingResourceException("Failed to find Item!", itemId.namespace(), itemId.key()); return itemStack.get(item).clone(); diff --git a/core/src/main/java/com/volmit/iris/core/link/ExecutableItemsDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/ExecutableItemsDataProvider.java index 8112a4595..27a3251b2 100644 --- a/core/src/main/java/com/volmit/iris/core/link/ExecutableItemsDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/ExecutableItemsDataProvider.java @@ -3,6 +3,7 @@ package com.volmit.iris.core.link; import com.ssomar.score.api.executableitems.ExecutableItemsAPI; import com.volmit.iris.Iris; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; import org.bukkit.block.data.BlockData; import org.bukkit.inventory.ItemStack; @@ -20,12 +21,12 @@ public class ExecutableItemsDataProvider extends ExternalDataProvider { } @Override - public BlockData getBlockData(Identifier blockId) throws MissingResourceException { + public BlockData getBlockData(Identifier blockId, KMap state) throws MissingResourceException { throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key()); } @Override - public ItemStack getItemStack(Identifier itemId) throws MissingResourceException { + public ItemStack getItemStack(Identifier itemId, KMap customNbt) throws MissingResourceException { return ExecutableItemsAPI.getExecutableItemsManager().getExecutableItem(itemId.key()) .map(item -> item.buildItem(1, Optional.empty())) .orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key())); diff --git a/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java index 7e3b4d00e..77e2b9c90 100644 --- a/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java @@ -1,6 +1,7 @@ package com.volmit.iris.core.link; import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.util.collection.KMap; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.bukkit.Bukkit; @@ -27,10 +28,19 @@ public abstract class ExternalDataProvider { public abstract void init(); - public abstract BlockData getBlockData(Identifier blockId) throws MissingResourceException; + public BlockData getBlockData(Identifier blockId) throws MissingResourceException { + return getBlockData(blockId, new KMap<>()); + } - public abstract ItemStack getItemStack(Identifier itemId) throws MissingResourceException; - public void processUpdate(Engine engine, Block block, Identifier blockId) {}; + public abstract BlockData getBlockData(Identifier blockId, KMap state) throws MissingResourceException; + + public ItemStack getItemStack(Identifier itemId) throws MissingResourceException { + return getItemStack(itemId, new KMap<>()); + } + + public abstract ItemStack getItemStack(Identifier itemId, KMap customNbt) throws MissingResourceException; + + public void processUpdate(Engine engine, Block block, Identifier blockId) {} public abstract Identifier[] getBlockTypes(); diff --git a/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java index 44c695a28..21207a22f 100644 --- a/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java @@ -2,8 +2,10 @@ package com.volmit.iris.core.link; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.service.ExternalDataSVC; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.data.IrisBlockData; import com.volmit.iris.util.reflect.WrappedField; import com.volmit.iris.util.reflect.WrappedReturningMethod; @@ -50,7 +52,7 @@ public class HMCLeavesDataProvider extends ExternalDataProvider { } @Override - public BlockData getBlockData(Identifier blockId) throws MissingResourceException { + public BlockData getBlockData(Identifier blockId, KMap state) throws MissingResourceException { Object o = blockDataMap.get(blockId.key()); if (o == null) throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key()); @@ -60,11 +62,11 @@ public class HMCLeavesDataProvider extends ExternalDataProvider { BlockData blockData = Bukkit.createBlockData(material); if (IrisSettings.get().getGenerator().preventLeafDecay && blockData instanceof Leaves leaves) leaves.setPersistent(true); - return new IrisBlockData(blockData, blockId); + return new IrisBlockData(blockData, ExternalDataSVC.buildState(blockId, state)); } @Override - public ItemStack getItemStack(Identifier itemId) throws MissingResourceException { + public ItemStack getItemStack(Identifier itemId, KMap customNbt) throws MissingResourceException { if (!itemDataField.containsKey(itemId.key())) throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()); return itemDataField.get(itemId.key()).get(); @@ -72,6 +74,8 @@ public class HMCLeavesDataProvider extends ExternalDataProvider { @Override public void processUpdate(Engine engine, Block block, Identifier blockId) { + var pair = ExternalDataSVC.parseState(blockId); + blockId = pair.getA(); Boolean result = setCustomBlock.invoke(apiInstance, new Object[]{block.getLocation(), blockId.key(), false}); if (result == null || !result) Iris.warn("Failed to set custom block! " + blockId.key() + " " + block.getX() + " " + block.getY() + " " + block.getZ()); diff --git a/core/src/main/java/com/volmit/iris/core/link/ItemAdderDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/ItemAdderDataProvider.java index 67f594323..e08e8fd7d 100644 --- a/core/src/main/java/com/volmit/iris/core/link/ItemAdderDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/ItemAdderDataProvider.java @@ -2,6 +2,7 @@ package com.volmit.iris.core.link; import com.volmit.iris.Iris; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; import dev.lone.itemsadder.api.CustomBlock; import dev.lone.itemsadder.api.CustomStack; import org.bukkit.block.data.BlockData; @@ -32,12 +33,12 @@ public class ItemAdderDataProvider extends ExternalDataProvider { } @Override - public BlockData getBlockData(Identifier blockId) throws MissingResourceException { + public BlockData getBlockData(Identifier blockId, KMap state) throws MissingResourceException { return CustomBlock.getBaseBlockData(blockId.toString()); } @Override - public ItemStack getItemStack(Identifier itemId) throws MissingResourceException { + public ItemStack getItemStack(Identifier itemId, KMap customNbt) throws MissingResourceException { CustomStack stack = CustomStack.getInstance(itemId.toString()); if (stack == null) { throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()); diff --git a/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java index 4445f3e9d..b402f32ab 100644 --- a/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java @@ -2,6 +2,7 @@ package com.volmit.iris.core.link; import com.volmit.iris.Iris; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.scheduling.J; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.Type; @@ -26,7 +27,7 @@ public class MMOItemsDataProvider extends ExternalDataProvider { } @Override - public BlockData getBlockData(Identifier blockId) throws MissingResourceException { + public BlockData getBlockData(Identifier blockId, KMap state) throws MissingResourceException { int id = -1; try { id = Integer.parseInt(blockId.key()); @@ -37,12 +38,33 @@ public class MMOItemsDataProvider extends ExternalDataProvider { } @Override - public ItemStack getItemStack(Identifier itemId) throws MissingResourceException { + public ItemStack getItemStack(Identifier itemId, KMap customNbt) throws MissingResourceException { String[] parts = itemId.namespace().split("_", 2); if (parts.length != 2) throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()); CompletableFuture future = new CompletableFuture<>(); - Runnable run = () -> future.complete(api().getItem(parts[1], itemId.key())); + Runnable run = () -> { + try { + var type = api().getTypes().get(parts[1]); + int level = customNbt.containsKey("level") ? (int) customNbt.get("level") : -1; + var tier = api().getTiers().get(String.valueOf(customNbt.get("tier"))); + + ItemStack itemStack; + if (type == null) { + future.complete(null); + return; + } + + if (level != -1 && tier != null) { + itemStack = api().getItem(type, itemId.key(), level, tier); + } else { + itemStack = api().getItem(type, itemId.key()); + } + future.complete(itemStack); + } catch (Throwable e) { + future.completeExceptionally(e); + } + }; if (Bukkit.isPrimaryThread()) run.run(); else J.s(run); ItemStack item = null; diff --git a/core/src/main/java/com/volmit/iris/core/link/OraxenDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/OraxenDataProvider.java index 58e21883d..a685edc00 100644 --- a/core/src/main/java/com/volmit/iris/core/link/OraxenDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/OraxenDataProvider.java @@ -19,10 +19,16 @@ package com.volmit.iris.core.link; import com.volmit.iris.Iris; +import com.volmit.iris.core.nms.INMS; +import com.volmit.iris.core.nms.container.BiomeColor; +import com.volmit.iris.core.service.ExternalDataSVC; +import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.data.B; import com.volmit.iris.util.data.IrisBlockData; +import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.reflect.WrappedField; import io.th0rgal.oraxen.api.OraxenItems; import io.th0rgal.oraxen.items.ItemBuilder; @@ -36,15 +42,22 @@ import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureMechanic import io.th0rgal.oraxen.mechanics.provided.gameplay.noteblock.NoteBlockMechanicFactory; import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicFactory; import org.bukkit.Bukkit; +import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.MultipleFacing; +import org.bukkit.entity.Entity; +import org.bukkit.entity.ItemDisplay; +import org.bukkit.entity.ItemFrame; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.PotionMeta; import java.util.Map; import java.util.MissingResourceException; import java.util.Optional; +import java.util.function.Consumer; public class OraxenDataProvider extends ExternalDataProvider { @@ -66,7 +79,7 @@ public class OraxenDataProvider extends ExternalDataProvider { } @Override - public BlockData getBlockData(Identifier blockId) throws MissingResourceException { + public BlockData getBlockData(Identifier blockId, KMap state) throws MissingResourceException { MechanicFactory factory = getFactory(blockId); if (factory instanceof NoteBlockMechanicFactory f) return f.createNoteBlockData(blockId.key()); @@ -77,22 +90,70 @@ public class OraxenDataProvider extends ExternalDataProvider { } else if (factory instanceof StringBlockMechanicFactory f) { return f.createTripwireData(blockId.key()); } else if (factory instanceof FurnitureFactory) { - return new IrisBlockData(B.getAir(), blockId); + return new IrisBlockData(B.getAir(), ExternalDataSVC.buildState(blockId, state)); } else throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key()); } @Override - public ItemStack getItemStack(Identifier itemId) throws MissingResourceException { + public ItemStack getItemStack(Identifier itemId, KMap customNbt) throws MissingResourceException { Optional opt = OraxenItems.getOptionalItemById(itemId.key()); return opt.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key())).build(); } @Override public void processUpdate(Engine engine, Block block, Identifier blockId) { + var pair = ExternalDataSVC.parseState(blockId); + var state = pair.getB(); + blockId = pair.getA(); Mechanic mechanic = getFactory(blockId).getMechanic(blockId.key()); if (mechanic instanceof FurnitureMechanic f) { - f.place(block.getLocation()); + float yaw = 0; + BlockFace face = BlockFace.NORTH; + + long seed = engine.getSeedManager().getSeed() + Cache.key(block.getX(), block.getZ()) + block.getY(); + RNG rng = new RNG(seed); + if ("true".equals(state.get("randomYaw"))) { + yaw = rng.f(0, 360); + } else if (state.containsKey("yaw")) { + yaw = Float.parseFloat(state.get("yaw")); + } + if ("true".equals(state.get("randomFace"))) { + BlockFace[] faces = BlockFace.values(); + face = faces[rng.i(0, faces.length - 1)]; + } else if (state.containsKey("face")) { + face = BlockFace.valueOf(state.get("face").toUpperCase()); + } + if (face == BlockFace.SELF) { + face = BlockFace.NORTH; + } + ItemStack itemStack = OraxenItems.getItemById(f.getItemID()).build(); + Entity entity = f.place(block.getLocation(), itemStack, yaw, face, false); + + Consumer setter = null; + if (entity instanceof ItemFrame frame) { + itemStack = frame.getItem(); + setter = frame::setItem; + } else if (entity instanceof ItemDisplay display) { + itemStack = display.getItemStack(); + setter = display::setItemStack; + } + if (setter == null || itemStack == null) return; + + BiomeColor type = null; + try { + type = BiomeColor.valueOf(state.get("matchBiome").toUpperCase()); + } catch (NullPointerException | IllegalArgumentException ignored) {} + + if (type != null) { + var biomeColor = INMS.get().getBiomeColor(block.getLocation(), type); + var potionColor = Color.fromARGB(biomeColor.getAlpha(), biomeColor.getRed(), biomeColor.getGreen(), biomeColor.getBlue()); + if (itemStack.getItemMeta() instanceof PotionMeta meta) { + meta.setColor(potionColor); + itemStack.setItemMeta(meta); + } + } + setter.accept(itemStack); } } diff --git a/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java b/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java index e99478753..8ce6caba8 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java +++ b/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java @@ -20,6 +20,7 @@ package com.volmit.iris.core.nms.v1X; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMSBinding; +import com.volmit.iris.core.nms.container.BiomeColor; import com.volmit.iris.core.nms.container.BlockPos; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.util.collection.KList; @@ -40,6 +41,8 @@ import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.generator.ChunkGenerator; import org.bukkit.inventory.ItemStack; +import java.awt.*; + public class NMSBinding1X implements INMSBinding { private static final boolean supportsCustomHeight = testCustomHeight(); @@ -97,6 +100,11 @@ public class NMSBinding1X implements INMSBinding { return location.getWorld().spawnEntity(location, type); } + @Override + public Color getBiomeColor(Location location, BiomeColor type) { + return Color.GREEN; + } + @Override public void deserializeTile(CompoundTag s, Location newPosition) { diff --git a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java index e70e1c1d4..4c31f2312 100644 --- a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java @@ -20,8 +20,10 @@ package com.volmit.iris.core.service; import com.volmit.iris.Iris; import com.volmit.iris.core.link.*; +import com.volmit.iris.core.nms.container.Pair; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.plugin.IrisService; import lombok.Data; import org.bukkit.Bukkit; @@ -31,8 +33,8 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.server.PluginEnableEvent; import org.bukkit.inventory.ItemStack; -import java.util.MissingResourceException; -import java.util.Optional; +import java.util.*; +import java.util.stream.Collectors; @Data public class ExternalDataSVC implements IrisService { @@ -93,26 +95,29 @@ public class ExternalDataSVC implements IrisService { } } - public Optional getBlockData(Identifier key) { - Optional provider = activeProviders.stream().filter(p -> p.isValidProvider(key, false)).findFirst(); + public Optional getBlockData(final Identifier key) { + var pair = parseState(key); + Identifier mod = pair.getA(); + + Optional provider = activeProviders.stream().filter(p -> p.isValidProvider(mod, false)).findFirst(); if (provider.isEmpty()) return Optional.empty(); try { - return Optional.of(provider.get().getBlockData(key)); + return Optional.of(provider.get().getBlockData(mod, pair.getB())); } catch (MissingResourceException e) { Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]"); return Optional.empty(); } } - public Optional getItemStack(Identifier key) { + public Optional getItemStack(Identifier key, KMap customNbt) { Optional provider = activeProviders.stream().filter(p -> p.isValidProvider(key, true)).findFirst(); if (provider.isEmpty()) { Iris.warn("No matching Provider found for modded material \"%s\"!", key); return Optional.empty(); } try { - return Optional.of(provider.get().getItemStack(key)); + return Optional.of(provider.get().getItemStack(key, customNbt)); } catch (MissingResourceException e) { Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]"); return Optional.empty(); @@ -139,4 +144,27 @@ public class ExternalDataSVC implements IrisService { activeProviders.forEach(p -> names.add(p.getItemTypes())); return names.toArray(new Identifier[0]); } + + public static Pair> parseState(Identifier key) { + if (!key.key().contains("[") || !key.key().contains("]")) { + return new Pair<>(key, new KMap<>()); + } + String state = key.key().split("\\Q[\\E")[1].split("\\Q]\\E")[0]; + KMap stateMap = new KMap<>(); + if (!state.isEmpty()) { + Arrays.stream(state.split(",")).forEach(s -> stateMap.put(s.split("=")[0], s.split("=")[1])); + } + return new Pair<>(new Identifier(key.namespace(), key.key().split("\\Q[\\E")[0]), stateMap); + } + + public static Identifier buildState(Identifier key, KMap state) { + if (state.isEmpty()) { + return key; + } + String path = state.entrySet() + .stream() + .map(e -> e.getKey() + "=" + e.getValue()) + .collect(Collectors.joining(",", key.key() + "[", "]")); + return new Identifier(key.namespace(), path); + } } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisLoot.java b/core/src/main/java/com/volmit/iris/engine/object/IrisLoot.java index d7001f233..ae7f5e121 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisLoot.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisLoot.java @@ -29,7 +29,6 @@ import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.data.B; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; -import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.noise.CNG; import lombok.AllArgsConstructor; @@ -146,7 +145,7 @@ public class IrisLoot { // TODO Better Third Party Item Acquisition private ItemStack getItemStack(RNG rng) { if (!type.startsWith("minecraft:") && type.contains(":")) { - Optional opt = Iris.service(ExternalDataSVC.class).getItemStack(Identifier.fromString(type)); + Optional opt = Iris.service(ExternalDataSVC.class).getItemStack(Identifier.fromString(type), customNbt); if (opt.isEmpty()) { Iris.warn("Unknown Material: " + type); return new ItemStack(Material.AIR);