From e4a885a62ab1393002e4dad0fa0293ad81d18004 Mon Sep 17 00:00:00 2001 From: RecursivePineapple Date: Fri, 27 Dec 2024 00:51:48 -0500 Subject: [PATCH] Matter manipulator compat (#3222) Co-authored-by: Martin Robertz Co-authored-by: Maya <10861407+serenibyss@users.noreply.github.com> --- .../gregtech/api/enums/MetaTileEntityIDs.java | 2 + .../java/gregtech/api/enums/OrePrefixes.java | 51 +++++++ .../api/interfaces/tileentity/ICoverable.java | 4 + .../tileentity/IRedstoneEmitter.java | 19 +++ .../metatileentity/BaseMetaTileEntity.java | 4 + .../metatileentity/CoverableTileEntity.java | 30 ++++ .../java/gregtech/api/util/GTUtility.java | 134 +++++++++++++++++- .../tileentities/base/TileEntityBase.java | 35 +++++ .../metaTileEntity/multi/base/Parameters.java | 31 ++++ 9 files changed, 309 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java b/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java index 1ab129e110e..4e7c28a2bda 100644 --- a/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java +++ b/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java @@ -759,6 +759,8 @@ public enum MetaTileEntityIDs { SOLAR_PANEL_LuV(2736), SOLAR_PANEL_ZPM(2737), SOLAR_PANEL_UV(2738), + MATTER_MANIPULATOR_UPLINK(2750), + HATCH_MATTER_MANIPULATOR_UPLINK_ME(2751), INDUSTRIAL_LASER_ENGRAVER_CONTROLLER(3004), INDUSTRIAL_COMPRESSOR_CONTROLLER(3005), HIP_COMPRESSOR_CONTROLLER(3006), diff --git a/src/main/java/gregtech/api/enums/OrePrefixes.java b/src/main/java/gregtech/api/enums/OrePrefixes.java index 159e0461881..81259da9bfd 100644 --- a/src/main/java/gregtech/api/enums/OrePrefixes.java +++ b/src/main/java/gregtech/api/enums/OrePrefixes.java @@ -12,6 +12,7 @@ import java.util.List; import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.OreDictionary; import com.google.common.collect.ImmutableList; @@ -25,7 +26,10 @@ import gregtech.api.objects.MaterialStack; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.api.util.GTUtility.ItemId; import gregtech.loaders.materialprocessing.ProcessingModSupport; +import it.unimi.dsi.fastutil.Pair; +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; import it.unimi.dsi.fastutil.objects.ObjectSet; @@ -1184,6 +1188,53 @@ public static String stripPrefix(String aOre) { return aOre; } + public static Pair detectPrefix(String oredictName) { + for (OrePrefixes prefix : values()) { + if (oredictName.startsWith(prefix.name())) { + return Pair.of( + prefix, + oredictName.substring( + prefix.name() + .length())); + } + } + + return null; + } + + private static final ThreadLocal>>> PREFIX_CACHE = ThreadLocal + .withInitial(Object2ObjectLinkedOpenHashMap::new); + + public static ImmutableList> detectPrefix(ItemStack stack) { + Object2ObjectLinkedOpenHashMap>> cache = PREFIX_CACHE.get(); + + ItemId itemId = ItemId.create(stack); + + var cacheResult = cache.getAndMoveToFirst(itemId); + + if (cacheResult != null) return cacheResult; + + ImmutableList.Builder> result = ImmutableList.builder(); + + for (int id : OreDictionary.getOreIDs(stack)) { + Pair p = detectPrefix(OreDictionary.getOreName(id)); + + if (p != null) { + result.add(p); + } + } + + ImmutableList> prefixes = result.build(); + + cache.putAndMoveToFirst(itemId, prefixes); + + while (cache.size() > 1024) { + cache.removeLast(); + } + + return prefixes; + } + public static String replacePrefix(String aOre, OrePrefixes aPrefix) { for (OrePrefixes tPrefix : values()) { if (aOre.startsWith(tPrefix.toString())) { diff --git a/src/main/java/gregtech/api/interfaces/tileentity/ICoverable.java b/src/main/java/gregtech/api/interfaces/tileentity/ICoverable.java index 00ae2db9bd0..87b87598cb6 100644 --- a/src/main/java/gregtech/api/interfaces/tileentity/ICoverable.java +++ b/src/main/java/gregtech/api/interfaces/tileentity/ICoverable.java @@ -17,6 +17,10 @@ public interface ICoverable extends IRedstoneTileEntity, IHasInventory, IBasicEn boolean dropCover(ForgeDirection side, ForgeDirection droppedSide, boolean aForced); + default ItemStack removeCoverAtSide(ForgeDirection side, boolean aForced) { + return null; + } + @Deprecated void setCoverDataAtSide(ForgeDirection side, int aData); diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IRedstoneEmitter.java b/src/main/java/gregtech/api/interfaces/tileentity/IRedstoneEmitter.java index 1b280184ce7..42dff0802dc 100644 --- a/src/main/java/gregtech/api/interfaces/tileentity/IRedstoneEmitter.java +++ b/src/main/java/gregtech/api/interfaces/tileentity/IRedstoneEmitter.java @@ -38,6 +38,25 @@ public interface IRedstoneEmitter extends IHasWorldObjectAndCoords { */ void setStrongOutputRedstoneSignal(ForgeDirection side, byte aStrength); + /** + * Sets the strength of the redstone signal on the given side to strong or weak. + * Does not change the actual signal. + * + * @param side Must not be UNKNOWN + * @param isStrong True = strong, false = weak + */ + default void setRedstoneOutputStrength(ForgeDirection side, boolean isStrong) {} + + /** + * Checks if the given side will output a strong redstone signal when emitting a redstone signal. + * + * @param side Must not be UNKNOWN + * @return True = strong signal, false = weak signal + */ + default boolean getRedstoneOutputStrength(ForgeDirection side) { + return false; + } + /** * Gets the Output for the comparator on the given Side */ diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java index 79cb8cccff3..a3ed50ef81a 100644 --- a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java @@ -1180,6 +1180,10 @@ public void generatePowerNodes() { } } + public void setCableUpdateDelay(int delay) { + cableUpdateDelay = delay; + } + @Override public long getOutputAmperage() { if (canAccessData() && mMetaTileEntity.isElectric()) return mMetaTileEntity.maxAmperesOut(); diff --git a/src/main/java/gregtech/api/metatileentity/CoverableTileEntity.java b/src/main/java/gregtech/api/metatileentity/CoverableTileEntity.java index c9376504f60..02877d8497f 100644 --- a/src/main/java/gregtech/api/metatileentity/CoverableTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/CoverableTileEntity.java @@ -421,6 +421,21 @@ public boolean dropCover(ForgeDirection side, ForgeDirection droppedSide, boolea return true; } + @Override + public ItemStack removeCoverAtSide(ForgeDirection side, boolean aForced) { + final CoverInfo coverInfo = getCoverInfoAtSide(side); + if (!coverInfo.isValid()) return null; + if (!coverInfo.onCoverRemoval(aForced) && !aForced) return null; + final ItemStack tStack = coverInfo.getDrop(); + if (tStack != null) { + coverInfo.onDropped(); + } + clearCoverInfoAtSide(side); + updateOutputRedstoneSignal(side); + + return tStack; + } + protected void onBaseTEDestroyed() { for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { final CoverInfo coverInfo = getCoverInfoAtSide(side); @@ -446,6 +461,21 @@ public void setStrongOutputRedstoneSignal(ForgeDirection side, byte strength) { setOutputRedstoneSignal(side, strength); } + @Override + public void setRedstoneOutputStrength(ForgeDirection side, boolean isStrong) { + if (isStrong) { + mStrongRedstone |= (byte) side.flag; + } else { + mStrongRedstone &= ~(byte) side.flag; + } + setOutputRedstoneSignal(side, mSidedRedstone[side.ordinal()]); + } + + @Override + public boolean getRedstoneOutputStrength(ForgeDirection side) { + return (mStrongRedstone & side.flag) != 0; + } + @Override public void setInternalOutputRedstoneSignal(ForgeDirection side, byte aStrength) { if (!getCoverBehaviorAtSideNew(side) diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index da805f995db..dc863c64cda 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -114,6 +114,8 @@ import net.minecraftforge.fluids.IFluidHandler; import net.minecraftforge.oredict.OreDictionary; +import org.joml.Vector3i; + import com.google.auto.value.AutoValue; import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableMap; @@ -4516,6 +4518,14 @@ public static int clamp(int val, int lo, int hi) { return MathHelper.clamp_int(val, lo, hi); } + public static int min(int first, int... rest) { + for (int i = 0; i < rest.length; i++) { + int l = rest[i]; + if (l < first) first = l; + } + return first; + } + public static long min(long first, long... rest) { for (int i = 0; i < rest.length; i++) { long l = rest[i]; @@ -4524,6 +4534,14 @@ public static long min(long first, long... rest) { return first; } + public static int max(int first, int... rest) { + for (int i = 0; i < rest.length; i++) { + int l = rest[i]; + if (l > first) first = l; + } + return first; + } + public static long max(long first, long... rest) { for (int i = 0; i < rest.length; i++) { long l = rest[i]; @@ -4536,10 +4554,41 @@ public static int ceilDiv(int lhs, int rhs) { return (lhs + rhs - 1) / rhs; } + /** Handles negatives properly, but it's slower than {@link #ceilDiv(int, int)}. */ + public static int ceilDiv2(int lhs, int rhs) { + int sign = signum(lhs) * signum(rhs); + + if (lhs == 0) return 0; + if (rhs == 0) throw new ArithmeticException("/ by zero"); + + lhs = Math.abs(lhs); + rhs = Math.abs(rhs); + + int unsigned = 1 + ((lhs - 1) / rhs); + + return unsigned * sign; + } + public static long ceilDiv(long lhs, long rhs) { return (lhs + rhs - 1) / rhs; } + public static int signum(int x) { + return x < 0 ? -1 : x > 0 ? 1 : 0; + } + + public static long signum(long x) { + return x < 0 ? -1 : x > 0 ? 1 : 0; + } + + public static Vector3i signum(Vector3i v) { + v.x = signum(v.x); + v.y = signum(v.y); + v.z = signum(v.z); + + return v; + } + /** * Hash an item stack for the purpose of storing hash across launches */ @@ -4781,6 +4830,14 @@ public static ItemId createAsWildcard(ItemStack itemStack) { return new AutoValue_GTUtility_ItemId(itemStack.getItem(), W, null, null); } + public static ItemId createAsWildcardWithNBT(ItemStack itemStack) { + NBTTagCompound nbt = itemStack.getTagCompound(); + if (nbt != null) { + nbt = (NBTTagCompound) nbt.copy(); + } + return new AutoValue_GTUtility_ItemId(itemStack.getItem(), W, nbt, null); + } + /** * This method stores NBT as null. */ @@ -4839,9 +4896,84 @@ public NBTTagCompound writeToNBT() { @Nonnull public ItemStack getItemStack() { ItemStack itemStack = new ItemStack(item(), 1, metaData()); - itemStack.setTagCompound(nbt()); + NBTTagCompound nbt = nbt(); + itemStack.setTagCompound(nbt == null ? null : (NBTTagCompound) nbt.copy()); return itemStack; } + + @Nonnull + public ItemStack getItemStack(int stackSize) { + ItemStack itemStack = new ItemStack(item(), stackSize, metaData()); + NBTTagCompound nbt = nbt(); + itemStack.setTagCompound(nbt == null ? null : (NBTTagCompound) nbt.copy()); + return itemStack; + } + } + + @AutoValue + public abstract static class FluidId { + + public static FluidId create(NBTTagCompound tag) { + return new AutoValue_GTUtility_FluidId( + FluidRegistry.getFluid(tag.getString("FluidName")), + tag.hasKey("Tag", Constants.NBT.TAG_COMPOUND) ? tag.getCompoundTag("Tag") : null, + tag.hasKey("Amount", Constants.NBT.TAG_INT) ? tag.getInteger("Amount") : null); + } + + public NBTTagCompound writeToNBT() { + NBTTagCompound tag = new NBTTagCompound(); + tag.setString("FluidName", fluid().getName()); + if (nbt() != null) tag.setTag("Tag", nbt()); + Integer amount = amount(); + if (amount != null) tag.setInteger("Amount", amount); + return tag; + } + + public static FluidId create(FluidStack fluidStack) { + return createWithCopy(fluidStack.getFluid(), null, fluidStack.tag); + } + + public static FluidId createWithAmount(FluidStack fluidStack) { + return createWithCopy(fluidStack.getFluid(), (Integer) fluidStack.amount, fluidStack.tag); + } + + public static FluidId create(Fluid fluid) { + return createNoCopy(fluid, null, null); + } + + public static FluidId createWithCopy(Fluid fluid, Integer amount, @Nullable NBTTagCompound nbt) { + if (nbt != null) { + nbt = (NBTTagCompound) nbt.copy(); + } + return new AutoValue_GTUtility_FluidId(fluid, nbt, amount); + } + + /** + * This method does not copy the NBT tag. + */ + public static FluidId createNoCopy(Fluid fluid, Integer amount, @Nullable NBTTagCompound nbt) { + return new AutoValue_GTUtility_FluidId(fluid, nbt, amount); + } + + protected abstract Fluid fluid(); + + @Nullable + protected abstract NBTTagCompound nbt(); + + @Nullable + protected abstract Integer amount(); + + @Nonnull + public FluidStack getFluidStack() { + NBTTagCompound nbt = nbt(); + return new FluidStack(fluid(), 1, nbt != null ? (NBTTagCompound) nbt.copy() : null); + } + + @Nonnull + public FluidStack getFluidStack(int amount) { + NBTTagCompound nbt = nbt(); + return new FluidStack(fluid(), amount, nbt != null ? (NBTTagCompound) nbt.copy() : null); + } } public static int getPlasmaFuelValueInEUPerLiterFromMaterial(Materials material) { diff --git a/src/main/java/gtPlusPlus/core/tileentities/base/TileEntityBase.java b/src/main/java/gtPlusPlus/core/tileentities/base/TileEntityBase.java index 811fb0cab13..63a2d8329bf 100644 --- a/src/main/java/gtPlusPlus/core/tileentities/base/TileEntityBase.java +++ b/src/main/java/gtPlusPlus/core/tileentities/base/TileEntityBase.java @@ -1063,6 +1063,26 @@ public boolean dropCover(ForgeDirection side, ForgeDirection droppedSide, boolea return false; } + @Override + public ItemStack removeCoverAtSide(ForgeDirection side, boolean aForced) { + if (getCoverBehaviorAtSide(side) + .onCoverRemoval(side, getCoverIDAtSide(side), mCoverData[side.ordinal()], this, aForced) || aForced) { + ItemStack tStack = getCoverBehaviorAtSide(side) + .getDrop(side, getCoverIDAtSide(side), getCoverDataAtSide(side), this); + if (tStack != null) { + tStack.setTagCompound(null); + } + setCoverIDAtSide(side, 0); + if (mMetaTileEntity.hasSidedRedstoneOutputBehavior()) { + setOutputRedstoneSignal(side, (byte) 0); + } else { + setOutputRedstoneSignal(side, (byte) 15); + } + return tStack; + } + return null; + } + public String getOwnerName() { if (GTUtility.isStringInvalid(mOwnerName)) return "Player"; return mOwnerName; @@ -1092,6 +1112,21 @@ public void setStrongOutputRedstoneSignal(ForgeDirection side, byte aStrength) { setOutputRedstoneSignal(side, aStrength); } + @Override + public void setRedstoneOutputStrength(ForgeDirection side, boolean isStrong) { + if (isStrong) { + mStrongRedstone |= (byte) side.flag; + } else { + mStrongRedstone &= ~(byte) side.flag; + } + setOutputRedstoneSignal(side, mSidedRedstone[side.ordinal()]); + } + + @Override + public boolean getRedstoneOutputStrength(ForgeDirection side) { + return (mStrongRedstone & side.flag) != 0; + } + @Override public long injectEnergyUnits(ForgeDirection side, long aVoltage, long aAmperage) { if (!canAccessData() || !mMetaTileEntity.isElectric() diff --git a/src/main/java/tectech/thing/metaTileEntity/multi/base/Parameters.java b/src/main/java/tectech/thing/metaTileEntity/multi/base/Parameters.java index 27eb961166e..55c78712574 100644 --- a/src/main/java/tectech/thing/metaTileEntity/multi/base/Parameters.java +++ b/src/main/java/tectech/thing/metaTileEntity/multi/base/Parameters.java @@ -1,6 +1,9 @@ package tectech.thing.metaTileEntity.multi.base; import java.util.ArrayList; +import java.util.Arrays; + +import tectech.thing.metaTileEntity.multi.base.Parameters.Group.ParameterIn; /** * Instantiate parameters as field in parametersInstantiation_EM(); @@ -93,6 +96,34 @@ public Group getGroup(int hatchNo) { return groups[hatchNo] != null ? groups[hatchNo] : new Group(hatchNo, false); } + public boolean hasInputs() { + return !parameterInArrayList.isEmpty(); + } + + public double[] getInputs() { + return Arrays.copyOf(iParamsIn, iParamsIn.length); + } + + public void setInputs(double[] inputs) { + if (inputs.length != iParamsIn.length) { + throw new IllegalArgumentException("inputs must be the same length as iParamsIn (20)"); + } + + for (int i = 0; i < iParamsIn.length; i++) { + int hatch = i % 10; + int paramId = i / 10; + + Group group = groups[hatch]; + + if (group != null && (parent.mMaxProgresstime <= 0 || group.updateWhileRunning)) { + ParameterIn param = group.parameterIn[paramId]; + if (param != null) { + param.set(inputs[i] < 0 ? 0 : inputs[i]); + } + } + } + } + public interface IParameter { double get();