diff options
author | D-Cysteine <54219287+D-Cysteine@users.noreply.github.com> | 2021-12-08 16:49:20 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-09 00:49:20 +0100 |
commit | 695012134efafe33c839a26b4b00e14718ed74fa (patch) | |
tree | cf6dce3626c7ab1ae383c1651f24405b96c39652 /src/main/java/gregtech/common/covers/GT_Cover_ItemMeter.java | |
parent | 0b70f6cd6ff8b224600fc8e47816912aa8fce223 (diff) | |
download | GT5-Unofficial-695012134efafe33c839a26b4b00e14718ed74fa.tar.gz GT5-Unofficial-695012134efafe33c839a26b4b00e14718ed74fa.tar.bz2 GT5-Unofficial-695012134efafe33c839a26b4b00e14718ed74fa.zip |
Add threshold support to item and fluid covers (#785)
* Add threshold support to item and fluid covers
* Switch to storing in NBT
* Add handling for migration path
* Adjust item threshold max value
Diffstat (limited to 'src/main/java/gregtech/common/covers/GT_Cover_ItemMeter.java')
-rw-r--r-- | src/main/java/gregtech/common/covers/GT_Cover_ItemMeter.java | 402 |
1 files changed, 264 insertions, 138 deletions
diff --git a/src/main/java/gregtech/common/covers/GT_Cover_ItemMeter.java b/src/main/java/gregtech/common/covers/GT_Cover_ItemMeter.java index a7aba3d829..718529894b 100644 --- a/src/main/java/gregtech/common/covers/GT_Cover_ItemMeter.java +++ b/src/main/java/gregtech/common/covers/GT_Cover_ItemMeter.java @@ -1,5 +1,6 @@ package gregtech.common.covers; +import com.google.common.io.ByteArrayDataInput; import gregtech.api.enums.GT_Values; import gregtech.api.gui.GT_GUICover; import gregtech.api.gui.widgets.GT_GuiFakeItemButton; @@ -9,40 +10,65 @@ import gregtech.api.gui.widgets.GT_GuiIntegerTextBox; import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.tileentity.ICoverable; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.net.GT_Packet_TileEntityCover; -import gregtech.api.util.GT_CoverBehavior; +import gregtech.api.net.GT_Packet_TileEntityCoverNew; +import gregtech.api.util.GT_CoverBehaviorBase; import gregtech.api.util.GT_Utility; +import gregtech.api.util.ISerializableObject; import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_OutputBus_ME; import gregtech.common.tileentities.storage.GT_MetaTileEntity_DigitalChestBase; +import io.netty.buffer.ByteBuf; import net.minecraft.client.gui.GuiButton; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; import net.minecraftforge.fluids.Fluid; -public class GT_Cover_ItemMeter extends GT_CoverBehavior { +import javax.annotation.Nonnull; - // format: - private static final int SLOT_MASK = 0x3FFFFFF; // 0 = all, 1 = 0 ... +public class GT_Cover_ItemMeter extends GT_CoverBehaviorBase<GT_Cover_ItemMeter.ItemMeterData> { + + // Legacy data format + private static final int SLOT_MASK = 0x3FFFFFFF; // 0 = all, 1 = 0 ... private static final int CONVERTED_BIT = 0x80000000; private static final int INVERT_BIT = 0x40000000; - @Override - public boolean isRedstoneSensitive(byte aSide, int aCoverID, int aCoverVariable, ICoverable aTileEntity, long aTimer) { - return false; + public GT_Cover_ItemMeter() { + super(ItemMeterData.class); } @Override - public int doCoverThings(byte aSide, byte aInputRedstone, int aCoverID, int aCoverVariable, ICoverable aTileEntity, long aTimer) { + public ItemMeterData createDataObject(int aLegacyData) { //Convert from ver. 5.09.33.50 - if ((CONVERTED_BIT & aCoverVariable) == 0) - if (aCoverVariable == 0) - aCoverVariable = CONVERTED_BIT; - else if (aCoverVariable == 1) - aCoverVariable = CONVERTED_BIT | INVERT_BIT; - else if (aCoverVariable > 1) - aCoverVariable = CONVERTED_BIT | Math.min((aCoverVariable - 2), SLOT_MASK); + if ((CONVERTED_BIT & aLegacyData) == 0) + if (aLegacyData == 0) + aLegacyData = CONVERTED_BIT; + else if (aLegacyData == 1) + aLegacyData = CONVERTED_BIT | INVERT_BIT; + else if (aLegacyData > 1) + aLegacyData = CONVERTED_BIT | Math.min((aLegacyData - 2), SLOT_MASK); + + boolean invert = (aLegacyData & INVERT_BIT) == INVERT_BIT; + int slot = (aLegacyData & SLOT_MASK) - 1; + + return new ItemMeterData(invert, slot, 0); + } + + @Override + public ItemMeterData createDataObject() { + return new ItemMeterData(); + } + @Override + protected boolean isRedstoneSensitiveImpl(byte aSide, int aCoverID, ItemMeterData aCoverVariable, ICoverable aTileEntity, long aTimer) { + return false; + } + + @Override + protected ItemMeterData doCoverThingsImpl(byte aSide, byte aInputRedstone, int aCoverID, ItemMeterData aCoverVariable, ICoverable aTileEntity, long aTimer) { long tMax = 0; long tUsed = 0; IMetaTileEntity mte = ((IGregTechTileEntity) aTileEntity).getMetaTileEntity(); @@ -58,8 +84,8 @@ public class GT_Cover_ItemMeter extends GT_CoverBehavior { tUsed = 64; } } else { - int[] tSlots = (aCoverVariable & SLOT_MASK) > 0 ? - new int[]{(aCoverVariable & SLOT_MASK) - 1} : + int[] tSlots = aCoverVariable.slot >= 0 ? + new int[]{aCoverVariable.slot} : aTileEntity.getAccessibleSlotsFromSide(aSide); for (int i : tSlots) { @@ -72,78 +98,96 @@ public class GT_Cover_ItemMeter extends GT_CoverBehavior { } } - boolean inverted = (aCoverVariable & INVERT_BIT) == INVERT_BIT; - if(tUsed==0)//nothing - aTileEntity.setOutputRedstoneSignal(aSide, (byte)(inverted ? 15 : 0)); - else if(tUsed >= tMax)//full - aTileEntity.setOutputRedstoneSignal(aSide, (byte)(inverted ? 0 : 15)); - else//1-14 range - aTileEntity.setOutputRedstoneSignal(aSide, (byte)(inverted ? 14-((14*tUsed)/tMax) : 1+((14*tUsed)/tMax)) ); + long redstoneSignal; + if (tUsed == 0L) { + // nothing + redstoneSignal = 0; + } else if (tUsed >= tMax) { + // full + redstoneSignal = 15; + } else { + // 1-14 range + redstoneSignal = 1 + (14 * tUsed) / tMax; + } + + if (aCoverVariable.inverted) { + redstoneSignal = 15 - redstoneSignal; + } + + if (aCoverVariable.threshold > 0) { + if (aCoverVariable.inverted && tUsed >= aCoverVariable.threshold) { + redstoneSignal = 0; + } else if (!aCoverVariable.inverted && tUsed < aCoverVariable.threshold) { + redstoneSignal = 0; + } + } + + aTileEntity.setOutputRedstoneSignal(aSide, (byte) redstoneSignal); return aCoverVariable; } @Override - public int onCoverScrewdriverclick(byte aSide, int aCoverID, int aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer, float aX, float aY, float aZ) { + protected ItemMeterData onCoverScrewdriverClickImpl(byte aSide, int aCoverID, ItemMeterData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer, float aX, float aY, float aZ) { if (aPlayer.isSneaking()) { - if ((aCoverVariable & INVERT_BIT) == INVERT_BIT) { - aCoverVariable = aCoverVariable & ~INVERT_BIT; - GT_Utility.sendChatToPlayer(aPlayer, trans("NORMAL","Normal")); + if (aCoverVariable.inverted) { + aCoverVariable.inverted = false; + GT_Utility.sendChatToPlayer(aPlayer, trans("055","Normal")); } else { - aCoverVariable = aCoverVariable | INVERT_BIT; - GT_Utility.sendChatToPlayer(aPlayer, trans("INVERTED","Inverted")); + aCoverVariable.inverted = true; + GT_Utility.sendChatToPlayer(aPlayer, trans("054","Inverted")); } - return aCoverVariable; - } + } else { + aCoverVariable.slot++; + if (aCoverVariable.slot > aTileEntity.getSizeInventory()) + aCoverVariable.slot = -1; - int slot = (aCoverVariable & SLOT_MASK) + 1; - if (slot > aTileEntity.getSizeInventory() || slot > SLOT_MASK) - slot = 0; + if (aCoverVariable.slot == -1) + GT_Utility.sendChatToPlayer(aPlayer, trans("053", "Slot: ") + trans("ALL", "All")); + else + GT_Utility.sendChatToPlayer(aPlayer, trans("053", "Slot: ") + aCoverVariable.slot); + } - if (slot == 0) - GT_Utility.sendChatToPlayer(aPlayer, trans("053", "Slot: ") + trans("ALL", "All")); - else - GT_Utility.sendChatToPlayer(aPlayer, trans("053", "Slot: ") + (slot - 1)); - return CONVERTED_BIT | (aCoverVariable & INVERT_BIT) | slot; + return aCoverVariable; } @Override - public boolean letsEnergyIn(byte aSide, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + protected boolean letsEnergyInImpl(byte aSide, int aCoverID, ItemMeterData aCoverVariable, ICoverable aTileEntity) { return true; } @Override - public boolean letsEnergyOut(byte aSide, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + protected boolean letsEnergyOutImpl(byte aSide, int aCoverID, ItemMeterData aCoverVariable, ICoverable aTileEntity) { return true; } @Override - public boolean letsFluidIn(byte aSide, int aCoverID, int aCoverVariable, Fluid aFluid, ICoverable aTileEntity) { + protected boolean letsFluidInImpl(byte aSide, int aCoverID, ItemMeterData aCoverVariable, Fluid aFluid, ICoverable aTileEntity) { return true; } @Override - public boolean letsFluidOut(byte aSide, int aCoverID, int aCoverVariable, Fluid aFluid, ICoverable aTileEntity) { + protected boolean letsFluidOutImpl(byte aSide, int aCoverID, ItemMeterData aCoverVariable, Fluid aFluid, ICoverable aTileEntity) { return true; } @Override - public boolean letsItemsIn(byte aSide, int aCoverID, int aCoverVariable, int aSlot, ICoverable aTileEntity) { + protected boolean letsItemsInImpl(byte aSide, int aCoverID, ItemMeterData aCoverVariable, int aSlot, ICoverable aTileEntity) { return true; } @Override - public boolean letsItemsOut(byte aSide, int aCoverID, int aCoverVariable, int aSlot, ICoverable aTileEntity) { + protected boolean letsItemsOutImpl(byte aSide, int aCoverID, ItemMeterData aCoverVariable, int aSlot, ICoverable aTileEntity) { return true; } @Override - public boolean manipulatesSidedRedstoneOutput(byte aSide, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + protected boolean manipulatesSidedRedstoneOutputImpl(byte aSide, int aCoverID, ItemMeterData aCoverVariable, ICoverable aTileEntity) { return true; } @Override - public int getTickRate(byte aSide, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + protected int getTickRateImpl(byte aSide, int aCoverID, ItemMeterData aCoverVariable, ICoverable aTileEntity) { return 5; } @@ -157,36 +201,97 @@ public class GT_Cover_ItemMeter extends GT_CoverBehavior { } @Override - public Object getClientGUI(byte aSide, int aCoverID, int coverData, ICoverable aTileEntity) { + protected Object getClientGUIImpl(byte aSide, int aCoverID, ItemMeterData coverData, ICoverable aTileEntity, EntityPlayer aPlayer, World aWorld) { return new GUI(aSide, aCoverID, coverData, aTileEntity); } + public static class ItemMeterData implements ISerializableObject { + private boolean inverted; + /** The special value {@code -1} means all slots. */ + private int slot; + /** The special value {@code 0} means threshold check is disabled. */ + private int threshold; + + public ItemMeterData() { + inverted = false; + slot = -1; + threshold = 0; + } + + public ItemMeterData(boolean inverted, int slot, int threshold) { + this.inverted = inverted; + this.slot = slot; + this.threshold = threshold; + } + + @Nonnull + @Override + public ISerializableObject copy() { + return new ItemMeterData(inverted, slot, threshold); + } + + @Nonnull + @Override + public NBTBase saveDataToNBT() { + NBTTagCompound tag = new NBTTagCompound(); + tag.setBoolean("invert", inverted); + tag.setInteger("slot", slot); + tag.setInteger("threshold", threshold); + return tag; + } + + @Override + public void writeToByteBuf(ByteBuf aBuf) { + aBuf.writeBoolean(inverted); + aBuf.writeInt(slot); + aBuf.writeInt(threshold); + } + + @Override + public void loadDataFromNBT(NBTBase aNBT) { + NBTTagCompound tag = (NBTTagCompound) aNBT; + inverted = tag.getBoolean("invert"); + slot = tag.getInteger("slot"); + threshold = tag.getInteger("threshold"); + } + + @Nonnull + @Override + public ISerializableObject readFromPacket(ByteArrayDataInput aBuf, EntityPlayerMP aPlayer) { + inverted = aBuf.readBoolean(); + slot = aBuf.readInt(); + threshold = aBuf.readInt(); + return this; + } + } + private class GUI extends GT_GUICover { private final byte side; private final int coverID; - private final GT_GuiIconCheckButton button; + private final GT_GuiIconCheckButton invertedButton; private final GT_GuiIntegerTextBox intSlot; private final GT_GuiFakeItemButton intSlotIcon; - private int coverVariable; + private final GT_GuiIntegerTextBox thresholdSlot; + private final ItemMeterData coverVariable; + + private final int maxSlot; private static final int startX = 10; private static final int startY = 25; private static final int spaceX = 18; private static final int spaceY = 18; - private final int maxSlot; - private final String ALL = trans("ALL", "All"); private final String INVERTED = trans("INVERTED","Inverted"); private final String NORMAL = trans("NORMAL","Normal"); - public GUI(byte aSide, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + public GUI(byte aSide, int aCoverID, ItemMeterData aCoverVariable, ICoverable aTileEntity) { super(aTileEntity, 176, 107, GT_Utility.intToStack(aCoverID)); this.side = aSide; this.coverID = aCoverID; this.coverVariable = aCoverVariable; - button = new GT_GuiIconCheckButton(this, 0, startX + spaceX*0, startY+spaceY*0, GT_GuiIcon.REDSTONE_ON, GT_GuiIcon.REDSTONE_OFF); + invertedButton = new GT_GuiIconCheckButton(this, 0, startX + spaceX*0, startY+spaceY*0, GT_GuiIcon.REDSTONE_ON, GT_GuiIcon.REDSTONE_OFF, INVERTED, NORMAL); intSlot = new GT_GuiIntegerTextBox(this, 1, startX + spaceX * 0, startY + spaceY * 1 + 2, spaceX * 2+5, 12); intSlot.setMaxStringLength(6); @@ -202,17 +307,17 @@ public class GT_Cover_ItemMeter extends GT_CoverBehavior { if (maxSlot == -1 || tile instanceof GT_MetaTileEntity_DigitalChestBase) intSlot.setEnabled(false); + + thresholdSlot = new GT_GuiIntegerTextBox(this, 2, startX + spaceX * 0, startY + spaceY * 2 + 2, spaceX * 2 + 5, 12); + thresholdSlot.setMaxStringLength(6); } @Override public void drawExtras(int mouseX, int mouseY, float parTicks) { super.drawExtras(mouseX, mouseY, parTicks); - if (isInverted()) - this.getFontRenderer().drawString(INVERTED, startX + spaceX*3, 4+startY+spaceY*0, 0xFF555555); - else - this.getFontRenderer().drawString(NORMAL, startX + spaceX*3, 4+startY+spaceY*0, 0xFF555555); - - this.getFontRenderer().drawString(trans("254", "Detect slot#"), startX + spaceX*3, 4+startY+spaceY*1, 0xFF555555); + this.getFontRenderer().drawString(coverVariable.inverted ? INVERTED : NORMAL, startX + spaceX*3, 4+startY+spaceY*0, 0xFF555555); + this.getFontRenderer().drawString(trans("254", "Detect slot#"), startX + spaceX*3, 4+startY+spaceY*1, 0xFF555555); + this.getFontRenderer().drawString(trans("221", "Item threshold"), startX + spaceX * 3, startY + spaceY * 2 + 4, 0xFF555555); } @Override @@ -224,109 +329,130 @@ public class GT_Cover_ItemMeter extends GT_CoverBehavior { @Override public void buttonClicked(GuiButton btn) { - if (isInverted()) - coverVariable = (coverVariable & ~INVERT_BIT); - else - coverVariable = (coverVariable | INVERT_BIT); - - GT_Values.NW.sendToServer(new GT_Packet_TileEntityCover(side, coverID, coverVariable, tile)); + coverVariable.inverted = !coverVariable.inverted; + GT_Values.NW.sendToServer(new GT_Packet_TileEntityCoverNew(side, coverID, coverVariable, tile)); update(); } - private void update() { - resetTextBox(intSlot); - button.setChecked(isInverted()); - - int slot = getSlot(); - if (slot < 0) { - intSlotIcon.setItem(null); - return; - } - if (tile instanceof TileEntity && !super.tile.isDead()) { - if (tile.getSizeInventory() >= slot) { - ItemStack item = tile.getStackInSlot(slot); - intSlotIcon.setItem(item); - return; - } - } - intSlotIcon.setItem(null); - } - @Override public void onMouseWheel(int x, int y, int delta) { - for (GT_GuiIntegerTextBox box : textBoxes) { - if (box.isFocused()) { - int step = Math.max(1, Math.abs(delta / 120)); - step = (isShiftKeyDown() ? 50 : isCtrlKeyDown() ? 5 : 1) * (delta > 0 ? step : -step); - int val = parseTextBox(box); + if (intSlot.isFocused()) { + int step = Math.max(1, Math.abs(delta / 120)); + step = (isShiftKeyDown() ? 50 : isCtrlKeyDown() ? 5 : 1) * (delta > 0 ? step : -step); + int val = parseTextBox(intSlot); - if (val < 0) - val = -1; + if (val < 0) + val = -1; - val = val + step; + val = val + step; - if (val < 0) - val = -1; - else if (val > maxSlot ) - val = maxSlot; + if (val < 0) + val = -1; + else if (val > maxSlot) + val = maxSlot; - box.setText(val < 0 ? ALL : String.valueOf(val)); - return; + intSlot.setText(val < 0 ? ALL : Integer.toString(val)); + } else if (thresholdSlot.isFocused()) { + int val = parseTextBox(thresholdSlot); + + int step = 1; + if (isShiftKeyDown()) { + step *= 64; + } + if (isCtrlKeyDown()) { + step *= 10; } + + val += step * Integer.signum(delta); + + int upperBound = maxSlot > 0 ? maxSlot * 64 : 999_999; + val = GT_Utility.clamp(val, 0, upperBound); + thresholdSlot.setText(Integer.toString(val)); } } @Override public void applyTextBox(GT_GuiIntegerTextBox box) { - int val = parseTextBox(box)+1; - - if (val > SLOT_MASK) - val = SLOT_MASK; - else if (val < 0) - val = 0; - - coverVariable = val | CONVERTED_BIT | (coverVariable & INVERT_BIT); + if (box == intSlot) { + coverVariable.slot = parseTextBox(box); + } else if (box == thresholdSlot) { + coverVariable.threshold = parseTextBox(thresholdSlot); + } - GT_Values.NW.sendToServer(new GT_Packet_TileEntityCover(side, coverID, coverVariable, tile)); + GT_Values.NW.sendToServer(new GT_Packet_TileEntityCoverNew(side, coverID, coverVariable, tile)); update(); } @Override public void resetTextBox(GT_GuiIntegerTextBox box) { - box.setText(getSlot() < 0 ? ALL : String.valueOf(getSlot())); + if (box == intSlot) { + intSlot.setText(coverVariable.slot < 0 ? ALL : Integer.toString(coverVariable.slot)); + } else if (box == thresholdSlot) { + thresholdSlot.setText(Integer.toString(coverVariable.threshold)); + } } - private int parseTextBox(GT_GuiIntegerTextBox box) { - String text = box.getText(); - if (text == null) - return -1; - text = text.trim(); - if (text.startsWith(ALL)) - text = text.substring(ALL.length()); - - if (text.isEmpty()) - return -1; - - int val; - try { - val = Integer.parseInt(text); - } catch (NumberFormatException e) { - return -1; - } + private void update() { + invertedButton.setChecked(coverVariable.inverted); + resetTextBox(intSlot); + resetTextBox(thresholdSlot); - if (val < 0) - return -1; - else if (maxSlot < val) - return maxSlot; - return val; + if (coverVariable.slot < 0) { + intSlotIcon.setItem(null); + return; + } + if (tile instanceof TileEntity && !super.tile.isDead()) { + if (tile.getSizeInventory() >= coverVariable.slot) { + ItemStack item = tile.getStackInSlot(coverVariable.slot); + intSlotIcon.setItem(item); + return; + } + } + intSlotIcon.setItem(null); } - private boolean isInverted() { - return ((coverVariable & INVERT_BIT) != 0); - } + private int parseTextBox(GT_GuiIntegerTextBox box) { + if (box == intSlot) { + String text = box.getText(); + if (text == null) + return -1; + text = text.trim(); + if (text.startsWith(ALL)) + text = text.substring(ALL.length()); + + if (text.isEmpty()) + return -1; + + int val; + try { + val = Integer.parseInt(text); + } catch (NumberFormatException e) { + return -1; + } + + if (val < 0) + return -1; + else if (maxSlot < val) + return maxSlot; + return val; + } else if (box == thresholdSlot) { + String text = box.getText(); + if (text == null) { + return 0; + } + + int val; + try { + val = Integer.parseInt(text.trim()); + } catch (NumberFormatException e) { + return 0; + } + + int upperBound = maxSlot > 0 ? maxSlot * 64 : 999_999; + return GT_Utility.clamp(val, 0, upperBound); + } - private int getSlot() { - return (coverVariable & SLOT_MASK) - 1; + throw new UnsupportedOperationException("Unknown text box: " + box); } } } |