improve custom block/item api to allow custom settings

This commit is contained in:
Julian Krings
2024-06-25 13:35:34 +02:00
parent 48f901fc8c
commit 29526a80a9
10 changed files with 163 additions and 28 deletions

View File

@@ -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<String, String> 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<String, Object> 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();

View File

@@ -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<String, String> 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<String, Object> 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()));

View File

@@ -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<String, String> state) throws MissingResourceException;
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
return getItemStack(itemId, new KMap<>());
}
public abstract ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException;
public void processUpdate(Engine engine, Block block, Identifier blockId) {}
public abstract Identifier[] getBlockTypes();

View File

@@ -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<String, String> 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<String, Object> 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());

View File

@@ -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<String, String> state) throws MissingResourceException {
return CustomBlock.getBaseBlockData(blockId.toString());
}
@Override
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
CustomStack stack = CustomStack.getInstance(itemId.toString());
if (stack == null) {
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());

View File

@@ -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<String, String> 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<String, Object> 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<ItemStack> 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;

View File

@@ -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<String, String> 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<String, Object> customNbt) throws MissingResourceException {
Optional<ItemBuilder> 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<ItemStack> 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);
}
}

View File

@@ -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) {

View File

@@ -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<BlockData> getBlockData(Identifier key) {
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, false)).findFirst();
public Optional<BlockData> getBlockData(final Identifier key) {
var pair = parseState(key);
Identifier mod = pair.getA();
Optional<ExternalDataProvider> 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<ItemStack> getItemStack(Identifier key) {
public Optional<ItemStack> getItemStack(Identifier key, KMap<String, Object> customNbt) {
Optional<ExternalDataProvider> 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<Identifier, KMap<String, String>> 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<String, String> 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<String, String> 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);
}
}

View File

@@ -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<ItemStack> opt = Iris.service(ExternalDataSVC.class).getItemStack(Identifier.fromString(type));
Optional<ItemStack> opt = Iris.service(ExternalDataSVC.class).getItemStack(Identifier.fromString(type), customNbt);
if (opt.isEmpty()) {
Iris.warn("Unknown Material: " + type);
return new ItemStack(Material.AIR);