package com.thebrokenrail.scriptcraft.api.bridge; import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; import com.thebrokenrail.scriptcraft.api.util.ValueUtil; import net.minecraft.nbt.AbstractListTag; import net.minecraft.nbt.AbstractNumberTag; import net.minecraft.nbt.ByteTag; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.DoubleTag; import net.minecraft.nbt.FloatTag; import net.minecraft.nbt.IntTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.LongTag; import net.minecraft.nbt.ShortTag; import net.minecraft.nbt.StringTag; import net.minecraft.nbt.Tag; import net.minecraft.util.math.MathHelper; import java.util.Locale; @SuppressWarnings({"rawtypes", "unchecked"}) class TagBridges { private static Object[] toOut(Tag obj) { Object[] out = new Object[2]; out[0] = false; out[1] = null; if (obj instanceof StringTag) { out[1] = obj.asString(); } else if (obj instanceof AbstractNumberTag) { out[1] = ((AbstractNumberTag) obj).getDouble(); } else if (obj instanceof AbstractListTag) { out[0] = true; out[1] = obj; } else if (obj instanceof CompoundTag) { out[1] = obj; } return out; } private static Tag toTag(Object obj, String numberType) { if (obj instanceof Tag) { return (Tag) obj; } else if (obj instanceof Boolean) { return ByteTag.of((Boolean) obj); } else if (obj instanceof Double) { double value = (Double) obj; numberType = numberType.toUpperCase(Locale.ROOT); switch (numberType.toUpperCase(Locale.ROOT)) { case "INT": { return IntTag.of(MathHelper.floor(value)); } case "BYTE": { return ByteTag.of((byte) (MathHelper.floor(value) & 255)); } case "DOUBLE": { return DoubleTag.of(value); } case "LONG": { return LongTag.of((long) Math.floor(value)); } case "FLOAT": { return FloatTag.of((float) value); } case "SHORT": { return ShortTag.of((short) (MathHelper.floor(value) & '\uffff')); } default: { throw new RuntimeException("Invalid Number Type: " + numberType); } } } else if (obj instanceof String) { return StringTag.of((String) obj); } else { return null; } } static void register() { ScriptCraftCore.addBridge("CompoundTag.get", args -> { CompoundTag tag = (CompoundTag) args[0]; Tag obj = tag.get((String) args[1]); return toOut(obj); }); ScriptCraftCore.addBridge("CompoundTag.set", args -> { CompoundTag tag = (CompoundTag) args[0]; tag.put((String) args[1], toTag(args[2], (String) args[3])); return null; }); ScriptCraftCore.addBridge("CompoundTag.keys", args -> { CompoundTag tag = (CompoundTag) args[0]; return tag.getKeys().toArray(new String[0]); }); ScriptCraftCore.addBridge("CompoundTag.isValid", args -> args[0] instanceof CompoundTag); ScriptCraftCore.addBridge("ListTag.get", args -> { AbstractListTag tag = (AbstractListTag) args[0]; Tag obj = tag.get((int) ValueUtil.toDouble(args[1], 0)); return toOut(obj); }); ScriptCraftCore.addBridge("ListTag.set", args -> { AbstractListTag tag = (AbstractListTag) args[0]; tag.set((int) ValueUtil.toDouble(args[1], 0), toTag(args[2], (String) args[3])); return null; }); ScriptCraftCore.addBridge("ListTag.size", args -> { AbstractListTag tag = (AbstractListTag) args[0]; return tag.size(); }); ScriptCraftCore.addBridge("ListTag.isValid", args -> args[0] instanceof ListTag); ScriptCraftCore.addBridge("CompoundTag.create", args -> new CompoundTag()); ScriptCraftCore.addBridge("ListTag.create", args -> new ListTag()); } }