diff --git a/build.gradle b/build.gradle index a23efc1..9cd7861 100644 --- a/build.gradle +++ b/build.gradle @@ -373,7 +373,7 @@ catch (Exception ignored) { // Pulls version first from the VERSION env and then git tag String identifiedVersion = null -String versionOverride = '0.0.17p6' +String versionOverride = '0.0.17p7' try { // Produce a version based on the tag, or for branches something like 0.2.2-configurable-maven-and-extras.38+43090270b6-dirty if (versionOverride == null) { diff --git a/src/main/java/reobf/proghatches/eucrafting/IEUManager.java b/src/main/java/reobf/proghatches/eucrafting/IEUManager.java index b701477..8669303 100644 --- a/src/main/java/reobf/proghatches/eucrafting/IEUManager.java +++ b/src/main/java/reobf/proghatches/eucrafting/IEUManager.java @@ -43,7 +43,7 @@ public default long inject(long a, long v) { }; public UUID getUUID(); - + public void refund(long amp); public long doInject(long a, long v); diff --git a/src/main/java/reobf/proghatches/eucrafting/PartEUP2PInterface.java b/src/main/java/reobf/proghatches/eucrafting/PartEUP2PInterface.java index 735cdc4..2dc29e5 100644 --- a/src/main/java/reobf/proghatches/eucrafting/PartEUP2PInterface.java +++ b/src/main/java/reobf/proghatches/eucrafting/PartEUP2PInterface.java @@ -3,12 +3,14 @@ import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; +import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.UUID; import java.util.function.BiFunction; import java.util.function.Consumer; +import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.IntStream; import net.minecraft.block.Block; @@ -21,6 +23,7 @@ import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.MinecraftServer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.util.StatCollector; @@ -86,6 +89,7 @@ import appeng.api.storage.data.IAEItemStack; import appeng.api.util.DimensionalCoord; import appeng.api.util.IConfigManager; +import appeng.container.ContainerNull; import appeng.helpers.DualityInterface; import appeng.helpers.IInterfaceHost; import appeng.helpers.IPriorityHost; @@ -121,7 +125,7 @@ //modified from PartFluidP2PInterface public class PartEUP2PInterface extends PartP2PTunnelStatic implements IGridTickable, IStorageMonitorable, IInventoryDestination, IDualHost, ISidedInventory, IAEAppEngInventory, - ITileStorageMonitorable, IPriorityHost, IInterfaceHost, IPartGT5Power, IGuiProvidingPart, IDrain { + ITileStorageMonitorable, IPriorityHost, IInterfaceHost, IPartGT5Power, IGuiProvidingPart, IDrain ,IInstantCompletable{ public static class WailaDataProvider extends BasePartWailaDataProvider { @Override @@ -158,17 +162,17 @@ public NBTTagCompound getNBTData(EntityPlayerMP player, IPart part, TileEntity t tag.setInteger("succs", pt.succs); tag.setInteger("fails", pt.fails); tag.setBoolean("validtile", pt.getTargetTile()!=null); - tag.setBoolean("pass", pt.pass); + tag.setInteger("pass", pt.pass); PartEUP2PInterface iface=pt.getInput(); if(iface!=null){ - boolean[] suc=new boolean[1]; + boolean[] suc=new boolean[]{true}; StringBuilder s=new StringBuilder(); if(iface.getTargetTile()==null) s.append("---"); else{ s.append(""+iface.pass); - suc[0]&=iface.pass; + suc[0]&=iface.pass>0; } try { iface.getOutputs().forEach(ss->{ @@ -176,7 +180,7 @@ public NBTTagCompound getNBTData(EntityPlayerMP player, IPart part, TileEntity t s.append("|---"); else{ s.append("|"+ss.pass); - suc[0]&=iface.pass; + suc[0]&=iface.pass>0; } }); @@ -254,18 +258,18 @@ public List getWailaBody(IPart part, List currentToolTip, IWaila if(validtile){ - currentToolTip.add(StatCollector.translateToLocalFormatted("proghatches.eu.interface.waila.halt_count", + /*currentToolTip.add(StatCollector.translateToLocalFormatted("proghatches.eu.interface.waila.halt_count", accessor.getNBTData().getInteger("succs"))); currentToolTip.add(StatCollector.translateToLocalFormatted("proghatches.eu.interface.waila.fail_count", accessor.getNBTData().getInteger("fails"))); - + */ currentToolTip.add(StatCollector.translateToLocalFormatted("proghatches.eu.interface.waila.pass", accessor.getNBTData().getInteger("pass"))); } if(accessor.getNBTData().hasKey("io_pass")) {currentToolTip.add( - StatCollector.translateToLocalFormatted("proghatches.eu.interface.waila.pass.p2p")+ - accessor.getNBTData().getString("io_pass")); + StatCollector.translateToLocalFormatted("proghatches.eu.interface.waila.pass.p2p", + accessor.getNBTData().getString("io_pass"))); } return super.getWailaBody(part, currentToolTip, accessor, config); @@ -502,6 +506,24 @@ public boolean refund(IMEInventory inv, IMEInventory } boolean prevPower; + public TileEntity getTargetInv(){ + TileEntity te; + if(data!=null){ + DimensionalCoord pos = data.getPos(); + te= data.getTile().getWorldObj().getTileEntity(pos.x,pos.y,pos.z); + }else{ + int x=this.host.getTile().xCoord; + int y=this.host.getTile().yCoord; + int z=this.host.getTile().zCoord; + ForgeDirection fd = this.getSide(); + te=this.host.getTile().getWorldObj().getTileEntity( + x+fd.offsetX,y+fd.offsetY,z+fd.offsetZ); + } + + return te; + + + } public IMetaTileEntity getTargetTile(){ TileEntity te; @@ -529,13 +551,24 @@ public IMetaTileEntity getTargetTile(){ } int fails; - boolean pass; + int pass=-2; private void resetIdleCheckStatus(boolean check) { + fails=0; succs=0; - pass=false; + pass=-1; + passReason=0; + if(MinecraftServer.getServer()!=null) + pushtick=getTick(); + } + private static int getTick(){ + if(MinecraftServer.getServer()!=null) + return MinecraftServer.getServer().getTickCounter(); + return 0; } + long pushtick; + int passReason; @Override public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLastCall) { @@ -543,29 +576,46 @@ public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLastCall) duality.tickingRequest(node, ticksSinceLastCall); dualityFluid.tickingRequest(node, ticksSinceLastCall); boolean ok = false; - /* if (!this.isOutput()) { - boolean red = this.redstone(); + ArrayList all = new ArrayList<>(); + + if (!this.isOutput()) { + HashSet dummy = new HashSet<>(); + all.add(this); try { - for (PartEUP2PInterface o : this.getOutputs()) { - red = red | o.redstone(); + this.getOutputs().forEach(all::add); + } catch (GridAccessException e) {} + //phase0 + for(PartEUP2PInterface part:all){ + boolean order=part.pushtick==getTick(); + if(part.pass==-1&&!order){ + part.pass=0; } - } catch (GridAccessException e) { - - e.printStackTrace(); - } - - if (prevPower == true && red == false) { - ok = true; - + + if(part.pass==0){ + IMetaTileEntity t = part.getTargetTile(); + if(t!=null&&t instanceof IIdleStateProvider){ + if(((IIdleStateProvider) t).failThisTick()){ + if(part.fails++==0){part.pass=1;if(part.passReason==0)part.passReason=2;};//fail 1 time, assume no valid inputs, just pass it + } + }else{ + dummy.add(part); + } + } + } + //phase1 + boolean allok=all.stream().filter(s->!dummy.contains(s)).map(s->s.pass==1).reduce(Boolean::logicalAnd).orElse(false); + if(allok){ + ok=true; + all.forEach(s->s.pass=2); } - - prevPower = red; - + + + } - */ArrayList all = new ArrayList<>(); - if (!this.isOutput()) { + + /*if (!this.isOutput()) { boolean[] hasFail=new boolean[1]; @@ -577,11 +627,9 @@ public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLastCall) IMetaTileEntity t = s.getTargetTile(); if(t!=null&&t instanceof IIdleStateProvider){ - if(((IIdleStateProvider) t).getIdle()==1){ - s.pass=true; - } + if(((IIdleStateProvider) t).failThisTick()){ - if(s.fails++==2){s.pass=true;};//fail 2 times, so assume no valid inputs, just pass it + if(s.fails++==0){s.pass=true;};//fail 2 times, so assume no valid inputs, just pass it } //if(!(!prev_pass&&pass)) if(!pass) @@ -593,7 +641,7 @@ public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLastCall) if(!hasFail[0]&&>0){ok=true;} } - + */ @@ -601,7 +649,7 @@ public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLastCall) - if (ok || all.stream().map(s->s.redstoneticks>0).findAny().isPresent()) { + if (ok || all.stream().filter(s->s.redstoneticks>0).findAny().isPresent()) { //all.forEach(s->s.resetIdleCheckStatus(false)); try { @@ -981,29 +1029,31 @@ public boolean pushPattern(ICraftingPatternDetails patternDetails, InventoryCraf return true; } if (patternDetails instanceof WrappedPatternDetail) { - + WrappedPatternDetail p = (WrappedPatternDetail) patternDetails; + InventoryCrafting neo =new InventoryCrafting(new ContainerNull(), table.getSizeInventory(), 1); int[] count = new int[1]; int size = table.getSizeInventory(); for (int i = 0; i < size; i++) { ItemStack is = table.getStackInSlot(i); if (is != null && is.getItem() == MyMod.eu_token && is.stackSize > 0) { count[0] += is.stackSize; + is=is.copy(); is.stackSize = 0; - table.setInventorySlotContents(i, is); - - break; - } + neo.setInventorySlotContents(i, is); + + }else + neo.setInventorySlotContents(i, is); ; } PartEUP2PInterface face = this; if (isP2POut()) { face = this.getInput(); } - boolean succ = duality.pushPattern(p.original, table); + boolean succ = duality.pushPattern(p.original, neo); if (succ) { if (face != null){ - face.amp = Math.max(face.amp, count[0]); + //face.amp = Math.max(face.amp, count[0]); face.resetIdleCheckStatus(true); try { @@ -1025,7 +1075,7 @@ public boolean pushPattern(ICraftingPatternDetails patternDetails, InventoryCraf @Override public boolean isBusy() { - return duality.isBusy(); + return duality.isBusy()||getTargetInv()==null; } @Override @@ -1066,7 +1116,8 @@ public void readFromNBT(NBTTagCompound data) { redstoneOverride = data.getBoolean("redstoneOverride"); fails=data.getInteger("fails"); succs=data.getInteger("succs"); - pass=data.getBoolean("pass"); + pass=data.getInteger("pass"); + passReason=data.getInteger("passReason"); is.clear(); IntStream.range(0, data.getInteger("pending_size")).forEach(s -> { @@ -1096,10 +1147,10 @@ public void writeToNBT(NBTTagCompound data) { data.setLong("expectedamp", expectedamp); data.setBoolean("redstoneOverride", redstoneOverride); data.setInteger("fails", fails); - data.setBoolean("pass", pass); + data.setInteger("pass", pass); data.setInteger("succs", succs); - + data.setInteger("passReason",passReason); for (int i = 0; i < is.size(); i++) { data.setTag("pending_" + i, is.get(i).writeToNBT(new NBTTagCompound())); } @@ -1655,4 +1706,22 @@ public ItemStack getSelfRep() { return new ItemStack(MyMod.euinterface_p2p); } + @Override + public int rows() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int rowSize() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void complete() { + returnItems(); + + } + } diff --git a/src/main/java/reobf/proghatches/eucrafting/TileFluidInterface_EU.java b/src/main/java/reobf/proghatches/eucrafting/TileFluidInterface_EU.java index 4f77b6d..e458151 100644 --- a/src/main/java/reobf/proghatches/eucrafting/TileFluidInterface_EU.java +++ b/src/main/java/reobf/proghatches/eucrafting/TileFluidInterface_EU.java @@ -40,6 +40,7 @@ import appeng.api.storage.IMEMonitor; import appeng.api.storage.data.IAEItemStack; import appeng.api.util.DimensionalCoord; +import appeng.container.ContainerNull; import appeng.me.GridAccessException; import appeng.me.cluster.implementations.CraftingCPUCluster; import appeng.tile.TileEvent; @@ -64,11 +65,14 @@ import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.MinecraftServer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.StatCollector; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import reobf.proghatches.eucrafting.IEUManager.IDrain; +import reobf.proghatches.eucrafting.TileFluidInterface_EU.SISOPatternDetail; +import reobf.proghatches.eucrafting.TileFluidInterface_EU.WrappedPatternDetail; import reobf.proghatches.lang.LangManager; import reobf.proghatches.main.MyMod; import reobf.proghatches.util.ProghatchesUtil; @@ -120,14 +124,14 @@ else if(!validtile){currenttip.add(StatCollector.translateToLocalFormatted("prog if(validtile){ - - currenttip.add(StatCollector.translateToLocalFormatted("proghatches.eu.interface.waila.halt_count", + currenttip.add(StatCollector.translateToLocalFormatted("proghatches.eu.interface.waila.pass", + accessor.getNBTData().getInteger("pass"))); + /*currenttip.add(StatCollector.translateToLocalFormatted("proghatches.eu.interface.waila.halt_count", accessor.getNBTData().getInteger("succs"))); currenttip.add(StatCollector.translateToLocalFormatted("proghatches.eu.interface.waila.fail_count", - accessor.getNBTData().getInteger("fails"))); + accessor.getNBTData().getInteger("fails")));*/ } - currenttip.add(StatCollector.translateToLocalFormatted("proghatches.eu.interface.waila.pass", - accessor.getNBTData().getInteger("pass"))); + /* * System.out.println( StatCollector.translateToLocal( * "proghatches.eu.interface.waila.AA")); @@ -156,8 +160,8 @@ public NBTTagCompound getNBTData(EntityPlayerMP player, TileEntity te, NBTTagCom tag.setInteger("fails", pt.fails); tag.setBoolean("validtile", pt.getTargetTile()!=null); tag.setBoolean("hasdir", pt.getUp().getOpposite()!=ForgeDirection.UNKNOWN); - tag.setBoolean("pass", pt.pass); - + tag.setInteger("pass", pt.pass); + tag.setInteger("passReason", pt.passReason); return tag; } }; @@ -192,7 +196,8 @@ public void read(NBTTagCompound data) { expectedamp = data.getLong("expectedamp"); succs=data.getInteger("succs"); fails=data.getInteger("fails"); - pass=data.getBoolean("pass"); + pass=data.getInteger("pass"); + passReason=data.getInteger("passReason"); is.clear(); IntStream.range(0, data.getInteger("pending_size")).forEach(s -> { @@ -247,7 +252,8 @@ public void write(NBTTagCompound data) { data.setLong("expectedamp", expectedamp); data.setInteger("fails", fails); data.setInteger("succs", succs); - data.setBoolean("pass", pass); + data.setInteger("pass", pass); + data.setInteger("passReason",passReason); for (int i = 0; i < is.size(); i++) { data.setTag("pending_" + i, is.get(i).writeToNBT(new NBTTagCompound())); } @@ -294,14 +300,28 @@ public IMetaTileEntity getTargetTile(){ return null; } + private static int getTick(){ + if(MinecraftServer.getServer()!=null) + return MinecraftServer.getServer().getTickCounter(); + return 0; + } private void resetIdleCheckStatus() { fails=0; succs=0; - pass=false; - + pass=-1; + passReason=0; + if(MinecraftServer.getServer()!=null) + pushtick=getTick(); } - boolean pass;int fails,succs; + int pass=-2; + //-2 new + //-1 prepare + //0 checking + //1 pass + //2 pass-refunded + int fails,succs; + int passReason; @Override public TickingRequest getTickingRequest(final IGridNode node) { return new TickingRequest(1, 1, false, false); @@ -313,7 +333,7 @@ public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLastCall) tick(); return TickRateModulation.SAME; } - + long pushtick; //@TileEvent(TileEventType.TICK) public void tick() { if (this.worldObj.isRemote) { @@ -333,19 +353,31 @@ public void tick() { try{ t = getTargetTile(); if(t!=null&&t instanceof IIdleStateProvider){ - //if(pass)return; - - if(((IIdleStateProvider) t).getIdle()==1){ - pass=true;succs++; - } + + boolean order=pushtick==getTick(); + //is pushpatten() executed first, or tick()? + //same tick means pushpatten() goes first, + //and we should wait for the next tick + //or info collected might be obsolete + if(pass==-1&&!order){ + pass=0; + } + if(pass==0){ + /*if(((IIdleStateProvider) t).getIdle()==1){ + pass=1;succs++; + if(passReason==0)passReason=1; + }*/ if(((IIdleStateProvider) t).failThisTick()){ - if(fails++==2){pass=true;};//fail 2 times, so assume no valid inputs, just pass it + if(fails++==0){pass=1;if(passReason==0)passReason=2;};//fail 1 time, assume no valid inputs, just pass it + } } - if(pass&&>0){ok=true;} + } }catch(Exception e){e.printStackTrace();;} + if(pass==1){pass=2;ok=true;} + if (ok || redstoneticks > 0) { //resetIdleCheckStatus(false); try { @@ -415,34 +447,39 @@ public boolean pushPattern(ICraftingPatternDetails patternDetails, InventoryCraf returnItems(); if (patternDetails instanceof SISOPatternDetail) { - is.add(((SISOPatternDetail) patternDetails).out); + // do not call returnItems() here, or items returned will not be // considered // as output return true; } if (patternDetails instanceof WrappedPatternDetail) { - + WrappedPatternDetail p = (WrappedPatternDetail) patternDetails; - + InventoryCrafting neo =new InventoryCrafting(new ContainerNull(), table.getSizeInventory(), 1); int[] count = new int[1]; int size = table.getSizeInventory(); for (int i = 0; i < size; i++) { ItemStack is = table.getStackInSlot(i); if (is != null && is.getItem() == MyMod.eu_token && is.stackSize > 0) { count[0] += is.stackSize; + is=is.copy(); is.stackSize = 0; - table.setInventorySlotContents(i, is); - - break; - } + neo.setInventorySlotContents(i, is); + + }else + neo.setInventorySlotContents(i, is); ; } - boolean succ = super.pushPattern(p.original, table); + + boolean succ = super.pushPattern(p.original, neo); if (succ) { - amp = Math.max(amp, count[0]); + + resetIdleCheckStatus(); + + is.add(p.extraOut0); } @@ -1153,7 +1190,7 @@ public void refund(long amp) { this.amp -= amp; } - + @Override public ItemStack getCrafterIcon() { return new ItemStack(MyMod.block_euinterface); diff --git a/src/main/java/reobf/proghatches/fmp/LazerLayer.java b/src/main/java/reobf/proghatches/fmp/LazerLayer.java index f970627..d470e1c 100644 --- a/src/main/java/reobf/proghatches/fmp/LazerLayer.java +++ b/src/main/java/reobf/proghatches/fmp/LazerLayer.java @@ -1,7 +1,19 @@ package reobf.proghatches.fmp; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + import appeng.api.parts.IPart; import appeng.api.parts.LayerBase; +import appeng.api.util.AEColor; +import appeng.fmp.CableBusPart; +import appeng.me.helpers.IGridProxyable; +import appeng.parts.AEBasePart; import gregtech.api.interfaces.tileentity.IColoredTileEntity; import net.minecraft.inventory.ISidedInventory; import net.minecraftforge.common.util.ForgeDirection; @@ -20,8 +32,19 @@ public boolean canConnect(ForgeDirection side) { public byte getColorization() { for(ForgeDirection side:ForgeDirection.VALID_DIRECTIONS){ IPart pt = getPart(side); - if(pt instanceof ILazer){return ((ILazer) pt).getColorization();} + if(pt instanceof ILazer){ + if(pt instanceof AEBasePart){ + AEColor col = ((AEBasePart) pt).getHost().getColor(); + if(col==AEColor.Transparent)return -1; + + return (byte) (15-col.ordinal()); + } + + + + } } + return -1; } @@ -29,12 +52,9 @@ public byte getColorization() { @Override public byte setColorization(byte aColor) { - for(ForgeDirection side:ForgeDirection.VALID_DIRECTIONS){ - IPart pt = getPart(side); - if(pt instanceof ILazer){return ((ILazer) pt).setColorization(aColor);} - } - + return -1; } - + + } diff --git a/src/main/java/reobf/proghatches/gt/metatileentity/BufferedDualInputHatch.java b/src/main/java/reobf/proghatches/gt/metatileentity/BufferedDualInputHatch.java index fefed7d..a2ec635 100644 --- a/src/main/java/reobf/proghatches/gt/metatileentity/BufferedDualInputHatch.java +++ b/src/main/java/reobf/proghatches/gt/metatileentity/BufferedDualInputHatch.java @@ -25,6 +25,9 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.lwjgl.input.Keyboard; + +import net.minecraft.client.Minecraft; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -58,11 +61,14 @@ import com.gtnewhorizons.modularui.api.math.Alignment; import com.gtnewhorizons.modularui.api.math.Pos2d; import com.gtnewhorizons.modularui.api.math.Size; +import com.gtnewhorizons.modularui.api.screen.ModularUIContext; import com.gtnewhorizons.modularui.api.screen.ModularWindow; import com.gtnewhorizons.modularui.api.screen.ModularWindow.Builder; import com.gtnewhorizons.modularui.api.screen.UIBuildContext; import com.gtnewhorizons.modularui.api.widget.IWidgetBuilder; +import com.gtnewhorizons.modularui.api.widget.Interactable; import com.gtnewhorizons.modularui.api.widget.Widget; +import com.gtnewhorizons.modularui.common.internal.network.NetworkUtils; import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot; import com.gtnewhorizons.modularui.common.widget.ButtonWidget; import com.gtnewhorizons.modularui.common.widget.CycleButtonWidget; @@ -77,6 +83,7 @@ import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import gregtech.api.enums.SoundResource; import gregtech.api.enums.ToolDictNames; import gregtech.api.gui.modularui.GT_UITextures; @@ -348,6 +355,7 @@ public NBTTagCompound toTag() { tag.setInteger("f", f); tag.setBoolean("recipeLocked", recipeLocked); tag.setBoolean("lock", lock); + tag.setInteger("unlockDelay",unlockDelay); return tag; } @@ -387,10 +395,13 @@ public void fromTag(NBTTagCompound tag) { if(tag.getInteger("f")>0)f = tag.getInteger("f"); recipeLocked = tag.getBoolean("recipeLocked"); lock = tag.getBoolean("lock"); + unlockDelay=tag.getInteger("unlockDelay"); } int v = 4; - + + int unlockDelay=0; + public void init(int item, int fluid) { i = item; f = fluid; @@ -407,12 +418,10 @@ private FluidTank[] initFluidTack(FluidTank[] t) { return t; } public boolean isAccessibleForMulti() { - //System.out.println(tickFirstClassify); - // System.out.println(currentTick()); - // System.out.println("-----------"); - return !isEmpty()&& - tickFirstClassify+20){ + unlockDelay--; + if(unlockDelay!=0)return false; + + } + } + for (FluidTank ft : mStoredFluidInternalSingle) { ft.setFluid(null); } @@ -447,10 +468,9 @@ public boolean clearRecipeIfNeeded() { mStoredItemInternalSingle[ii] = null; } - recipeLocked = false; return true; - } + }else{unlockDelay=0;} return false; } @@ -482,14 +502,14 @@ public void firstClassify(ListeningFluidTank[] fin, ItemStack[] iin) { mStoredItemInternal[ix] = Optional.ofNullable(iin[ix]).map(ItemStack::copy).orElse(null); iin[ix] = null; } - Long tick=tickFirstClassify+2; + /*Long tick=tickFirstClassify+2; if(!tick.equals(scheduled.peekFirst())) { scheduled.push(tick); - } + }*/ - //justHadNewItems = true; + justHadNewItems = true; onClassify(); programLocal(); } @@ -688,6 +708,7 @@ public boolean updateEveryTick() { private int sleepTime; private boolean isOnLastTick; // public boolean prevdirty; + public int preventSleep; @Override public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { super.onPostTick(aBaseMetaTileEntity, aTick); @@ -722,12 +743,13 @@ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { }else if(!sleep){ boolean inputEmpty=isInputEmpty();//not dirty but awake, check if need to sleep if(inputEmpty){ - + if(preventSleep==0) if(Config.sleep)sleep=true; }//Zzz } if(sleep)sleepTime++; + if(preventSleep>0){preventSleep--;sleep=false;} //System.out.println(sleep); @@ -991,8 +1013,44 @@ public List getExtraTooltip() { * inv0.recipeLocked, s->inv0.recipeLocked=s )); */ builder.widget(new FakeSyncWidget.StringSyncer(() -> inv0.toTag().toString(), s -> inv0.fromTag(cv(s)))); + ModularWindow wd = builder.build(); + + wd.addInteractionListener(new Interactable() { + @SideOnly(Side.CLIENT) + public boolean onKeyPressed(char character, int keyCode) { + if (!wd.isClientOnly()) { + + if ((keyCode == Keyboard.KEY_ESCAPE + || Minecraft.getMinecraft().gameSettings.keyBindInventory.getKeyCode() == keyCode) + && Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) { + ArrayList tmp = new ArrayList<>(); + + wd.getContext().getMainWindow().getContext().getOpenWindows().forEach(tmp::add); + //return true will not prevent further check(not properly implemented to me) + //so close all other sync windows + //and let it proceed, it will close this window + tmp.forEach(wdd -> { + if (wdd == wd) + return; + if (wdd == wd.getContext().getMainWindow()) + return; + wdd.getContext().sendClientPacket(ModularUIContext.DataCodes.CLOSE_WINDOW, null, wdd, + NetworkUtils.EMPTY_PACKET); + wdd.tryClose(); + }); + + return false; + } + } - return builder.build(); + return false; + } + + + + +}); + return wd; } private NBTTagCompound cv(String s) { @@ -1036,6 +1094,7 @@ ButtonWidget createPowerSwitchButton(IWidgetBuilder builder) { @Override public void addUIWidgets(Builder builder, UIBuildContext buildContext) { + Scrollable sc = new Scrollable().setVerticalScroll(); for (int i = 0; i < bufferNum; i++) { final int ii = i; @@ -1101,6 +1160,7 @@ public void loadNBTData(NBTTagCompound aNBT) { } justHadNewItems = aNBT.getBoolean("justHadNewItems"); updateEveryTick = aNBT.getBoolean("updateEveryTick"); + preventSleep=aNBT.getInteger("preventSleep"); super.loadNBTData(aNBT); } @@ -1113,6 +1173,7 @@ public void saveNBTData(NBTTagCompound aNBT) { aNBT.setBoolean("justHadNewItems", justHadNewItems); aNBT.setBoolean("updateEveryTick", updateEveryTick); + aNBT.setInteger("preventSleep",preventSleep ); super.saveNBTData(aNBT); } diff --git a/src/main/java/reobf/proghatches/item/DummySuper.java b/src/main/java/reobf/proghatches/item/DummySuper.java new file mode 100644 index 0000000..a0846d0 --- /dev/null +++ b/src/main/java/reobf/proghatches/item/DummySuper.java @@ -0,0 +1,23 @@ +package reobf.proghatches.item; + +import java.util.List; + +import com.google.common.base.Optional; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +public class DummySuper extends Item{ + + public DummySuper(double powerCapacity, Optional subName) { + //good job ff + } + + protected void addCheckedInformation(ItemStack p_77624_1_, EntityPlayer p_77624_2_, List p_77624_3_, + boolean p_77624_4_) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/reobf/proghatches/item/ItemMEPlunger.java b/src/main/java/reobf/proghatches/item/ItemMEPlunger.java new file mode 100644 index 0000000..9d78e85 --- /dev/null +++ b/src/main/java/reobf/proghatches/item/ItemMEPlunger.java @@ -0,0 +1,379 @@ +package reobf.proghatches.item; + +import java.util.HashMap; +import java.util.List; +import java.util.stream.IntStream; + +import com.google.common.base.Optional; +import com.gtnewhorizons.modularui.api.widget.Interactable; + +import appeng.api.AEApi; +import appeng.api.config.Actionable; +import appeng.api.features.INetworkEncodable; +import appeng.api.features.IWirelessTermHandler; +import appeng.api.implementations.items.IAEItemPowerStorage; +import appeng.api.implementations.tiles.IWirelessAccessPoint; +import appeng.api.networking.IGrid; +import appeng.api.networking.IGridHost; +import appeng.api.networking.IGridNode; +import appeng.api.networking.security.BaseActionSource; +import appeng.api.networking.security.IActionHost; +import appeng.api.networking.security.PlayerSource; +import appeng.api.networking.storage.IStorageGrid; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IAEItemStack; +import appeng.api.util.AECableType; +import appeng.api.util.WorldCoord; +import appeng.items.tools.powered.ToolWirelessTerminal; +import appeng.items.tools.powered.powersink.AEBasePoweredItem; +import appeng.tile.misc.TileSecurity; +import appeng.tile.networking.TileWireless; +import appeng.util.item.AEFluidStack; +import appeng.util.item.AEItemStack; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.enums.SoundResource; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.metatileentity.IMetaTileEntityItemPipe; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.items.GT_MetaBase_Item; +import gregtech.api.items.GT_MetaGenerated_Tool; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicTank; +import gregtech.api.util.GT_Utility; +import gregtech.common.tileentities.machines.IDualInputHatch; +import gregtech.common.tileentities.machines.IDualInputInventory; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidHandler; +import reobf.proghatches.gt.metatileentity.BufferedDualInputHatch; +import reobf.proghatches.lang.LangManager; + +public class ItemMEPlunger extends DummySuper implements INetworkEncodable { + + public IAEItemPowerStorage asPowerStorage() { + return (IAEItemPowerStorage) this; + } + + public ItemMEPlunger(double powerCapacity) { + super(powerCapacity, Optional.absent()); + } + + public static IGridNode getWirelessGrid(ItemStack is) { + if (is.getItem() instanceof ItemMEPlunger) { + String key = ((ItemMEPlunger) is.getItem()).getEncryptionKey(is); + IGridHost securityTerminal = (IGridHost) AEApi.instance().registries().locatable() + .getLocatableBy(Long.parseLong(key)); + if (securityTerminal == null) + return null; + return securityTerminal.getGridNode(ForgeDirection.UNKNOWN); + } + return null; + } + + public static IGridHost getWirelessGridHost(ItemStack is) { + if (is.getItem() instanceof ItemMEPlunger) { + String key = ((ItemMEPlunger) is.getItem()).getEncryptionKey(is); + IGridHost securityTerminal = (IGridHost) AEApi.instance().registries().locatable() + .getLocatableBy(Long.parseLong(key)); + if (securityTerminal == null) + return null; + return securityTerminal; + } + return null; + } + + private static final String LINK_KEY_STRING = "key"; + + @Override + public String getEncryptionKey(final ItemStack wirelessTerminal) { + if (wirelessTerminal == null) { + return null; + } + // Ensure the terminal has a tag + if (wirelessTerminal.hasTagCompound()) { + // Get the security terminal source key + String sourceKey = wirelessTerminal.getTagCompound().getString(LINK_KEY_STRING); + + // Ensure the source is not empty nor null + if ((sourceKey != null) && (!sourceKey.isEmpty())) { + // The terminal is linked. + return sourceKey; + } + } + + // Terminal is unlinked. + return ""; + } + + private NBTTagCompound ensureTagCompound(ItemStack is) { + if (!is.hasTagCompound()) { + is.setTagCompound(new NBTTagCompound()); + } + return is.getTagCompound(); + } + + @Override + public void setEncryptionKey(final ItemStack wirelessTerminal, final String sourceKey, final String name) { + final NBTTagCompound tag = ensureTagCompound(wirelessTerminal); + tag.setString(LINK_KEY_STRING, sourceKey); + } + + public boolean damage(ItemStack aStack) { + + return asPowerStorage().extractAEPower(aStack, 1000)>999; + + } +public boolean check(Entity player,IGrid grid){ + if(grid==null)return false; + for (IGridNode node : grid.getMachines(TileWireless.class)) { + IWirelessAccessPoint accessPoint = (IWirelessAccessPoint) node.getMachine(); + if (accessPoint.isActive() && accessPoint.getLocation().getDimension() == player.dimension) { + WorldCoord distance = accessPoint.getLocation() + .subtract((int) player.posX, (int) player.posY, (int) player.posZ); + int squaredDistance = distance.x * distance.x + distance.y * distance.y + distance.z * distance.z; + if (squaredDistance <= accessPoint.getRange() * accessPoint.getRange()) { + return true; + + } + } + }return false; +} + +@Override +public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, + float hitX, float hitY, float hitZ) { + + + + if(getEncryptionKey(stack).equals("")){ + if(!world.isRemote) + player.addChatComponentMessage(new ChatComponentTranslation("item.proghatch_me_plunger.unbound")); + return true;} + if( getWirelessGrid(stack)==null){ + if(!world.isRemote) + player.addChatComponentMessage(new ChatComponentTranslation("item.proghatch_me_plunger.unbound")); + return true;} + if(!check(player, getWirelessGrid(stack).getGrid())){ + if(!world.isRemote) + player.addChatComponentMessage(new ChatComponentTranslation("item.proghatch_me_plunger.range")); + return true;} + + + if (clearDual(stack, player, world, x, y, z, ForgeDirection.getOrientation(side))) { + return true; + } + ; + if (clearItem(stack, player, world, x, y, z, ForgeDirection.getOrientation(side))) { + return true; + } + ; + if (clearFluid(stack, player, world, x, y, z, ForgeDirection.getOrientation(side))) { + return true; + } + ; + return super.onItemUseFirst(stack, player, world, x, y, z, side, hitX, hitY, hitZ); + } + @SuppressWarnings({ "unchecked", "rawtypes" }) + public boolean clearDual(ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ, + ForgeDirection side) { + + if (aWorld.isRemote) { + return false; + } + TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ); + if (aTileEntity instanceof IGregTechTileEntity) { + IGregTechTileEntity tTileEntity = (IGregTechTileEntity) aTileEntity; + IMetaTileEntity mTileEntity = tTileEntity.getMetaTileEntity(); + if (mTileEntity instanceof IDualInputHatch/*BufferedDualInputHatch*/) { + IStorageGrid storage = getWirelessGrid(aStack).getGrid().getCache(IStorageGrid.class); + IDualInputHatch dual=(IDualInputHatch) mTileEntity; + for(IDualInputInventory inv:(Iterable)(Iterable)(()->dual.inventories())){ + if((aPlayer.capabilities.isCreativeMode)||damage(aStack)){}else{continue;} + + for(ItemStack is:inv.getItemInputs()){ + + IAEItemStack left = storage.getItemInventory() + .injectItems( + AEItemStack.create(is) + , + Actionable.MODULATE, + new PlayerSource(aPlayer, (IActionHost) getWirelessGridHost(aStack))); + is.stackSize=Optional.fromNullable(left).transform(s->s.getStackSize()).or(0l).intValue(); + } + for(FluidStack is:inv.getFluidInputs()){ + + IAEFluidStack left = storage.getFluidInventory() + .injectItems( + AEFluidStack.create(is) + , + Actionable.MODULATE, + new PlayerSource(aPlayer, (IActionHost) getWirelessGridHost(aStack))); + is.amount=Optional.fromNullable(left).transform(s->s.getStackSize()).or(0l).intValue(); + } + + GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_RUBBER_TRAMPOLINE, 1.0F, -1.0F, aX, aY, + aZ); + } + + return true; + } + + + + } + + return false; + } + public boolean clearFluid(ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ, + ForgeDirection side) { + if (aWorld.isRemote) { + return false; + } + + IStorageGrid fluid = getWirelessGrid(aStack).getGrid().getCache(IStorageGrid.class); + /* + * IAEItemStack notadd = + * fluid.getItemInventory().injectItems(null,Actionable.SIMULATE , new + * PlayerSource(aPlayer, (IActionHost) getWirelessGridHost(aStack)) ); + */ + + TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ); + if ((aTileEntity instanceof IFluidHandler)) { + for (ForgeDirection tDirection : ForgeDirection.VALID_DIRECTIONS) { + if (((IFluidHandler) aTileEntity).drain(tDirection, 1000, false) != null) { + if ((aPlayer.capabilities.isCreativeMode) || damage(aStack)) { + + IAEFluidStack notadd = fluid.getFluidInventory() + .injectItems( + AEFluidStack.create(((IFluidHandler) aTileEntity).drain(tDirection, + Integer.MAX_VALUE, false)), + Actionable.SIMULATE, + new PlayerSource(aPlayer, (IActionHost) getWirelessGridHost(aStack))); + + if (notadd != null && notadd.getStackSize() > 0) {continue;} + + fluid.getFluidInventory() + .injectItems( + AEFluidStack.create(((IFluidHandler) aTileEntity).drain(tDirection, + Integer.MAX_VALUE, true)), + Actionable.MODULATE, + new PlayerSource(aPlayer, (IActionHost) getWirelessGridHost(aStack))); + + + GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_RUBBER_TRAMPOLINE, 1.0F, -1.0F, + aX, aY, aZ); + return true; + } + } + } + } + if (aTileEntity instanceof IGregTechTileEntity) { + IGregTechTileEntity tTileEntity = (IGregTechTileEntity) aTileEntity; + IMetaTileEntity mTileEntity = tTileEntity.getMetaTileEntity(); + if (mTileEntity instanceof GT_MetaTileEntity_BasicTank) { + GT_MetaTileEntity_BasicTank machine = (GT_MetaTileEntity_BasicTank) mTileEntity; + if (machine.mFluid != null && machine.mFluid.amount > 0){}else return false; + // machine.mFluid.amount = machine.mFluid.amount - + // Math.min(machine.mFluid.amount, 1000); + + IAEFluidStack notadd = fluid.getFluidInventory().injectItems( + AEFluidStack.create(machine.mFluid.copy()), Actionable.SIMULATE, + new PlayerSource(aPlayer, (IActionHost) getWirelessGridHost(aStack))); + + if (notadd != null && notadd.getStackSize() > 0) { + + fluid.getFluidInventory().injectItems(AEFluidStack.create(machine.mFluid.copy()), + Actionable.MODULATE, + new PlayerSource(aPlayer, (IActionHost) getWirelessGridHost(aStack)) + + ); + machine.mFluid.amount =0; + } + + GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_RUBBER_TRAMPOLINE, 1.0F, -1.0F, aX, aY, + aZ); + return true; + } + } + return false; + } + + public boolean clearItem(ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ, + ForgeDirection side) { + if (aWorld.isRemote) { + return false; + } + TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ); + if (aTileEntity instanceof IGregTechTileEntity) { + IGregTechTileEntity gtTE = (IGregTechTileEntity) aTileEntity; + IMetaTileEntity tMetaTileEntity = gtTE.getMetaTileEntity(); + if ((tMetaTileEntity instanceof IMetaTileEntityItemPipe)) { + for (IMetaTileEntityItemPipe tTileEntity : GT_Utility + .sortMapByValuesAcending(IMetaTileEntityItemPipe.Util + .scanPipes((IMetaTileEntityItemPipe) tMetaTileEntity, new HashMap<>(), 0L, false, true)) + .keySet()) { + int i = 0; + for (int j = tTileEntity.getSizeInventory(); i < j; i++) { + if (tTileEntity.isValidSlot(i)) { + if ((tTileEntity.getStackInSlot(i) != null) + && ((aPlayer.capabilities.isCreativeMode) || damage(aStack))) { + + IStorageGrid item = getWirelessGrid(aStack).getGrid().getCache(IStorageGrid.class); + IAEItemStack notadd = item.getItemInventory().injectItems( + AEItemStack.create(tTileEntity.getStackInSlot(i)), Actionable.SIMULATE, + new PlayerSource(aPlayer, (IActionHost) getWirelessGridHost(aStack))); + if (notadd != null && notadd.getStackSize() > 0) { + continue; + } + + final ItemStack tStack = tTileEntity.decrStackSize(i, Integer.MAX_VALUE / 2); + if (tStack != null) { + item.getItemInventory().injectItems(AEItemStack.create(tStack), Actionable.MODULATE, + new PlayerSource(aPlayer, (IActionHost) getWirelessGridHost(aStack))); + // discard ret value + + GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_RUBBER_TRAMPOLINE, + 1.0F, -1.0F, aX, aY, aZ); + } + + } + } + } + } + return true; + } + } + return false; + } + @SideOnly(Side.CLIENT) + public void addCheckedInformation(final ItemStack p_77624_1_, final EntityPlayer p_77624_2_, final List p_77624_3_, + final boolean p_77624_4_) { + /* super.addInformation(stack, player, lines, displayMoreInfo); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + @SideOnly(Side.CLIENT) + public void addInformation(ItemStack p_77624_1_, EntityPlayer p_77624_2_, List p_77624_3_, boolean p_77624_4_) { +*/ + + IntStream + .range(0, + Integer.valueOf(StatCollector.translateToLocal( + "item.proghatch_me_plunger.tooltips"))) + .forEach(s -> p_77624_3_.add(LangManager.translateToLocal( + "item.proghatch_me_plunger.tooltips" + "." + s))); + + super.addCheckedInformation(p_77624_1_, p_77624_2_, p_77624_3_, p_77624_4_); + } +} diff --git a/src/main/java/reobf/proghatches/main/CommonProxy.java b/src/main/java/reobf/proghatches/main/CommonProxy.java index 87e94ee..e67a366 100644 --- a/src/main/java/reobf/proghatches/main/CommonProxy.java +++ b/src/main/java/reobf/proghatches/main/CommonProxy.java @@ -28,6 +28,7 @@ import reobf.proghatches.item.ItemDedicatedCover; import reobf.proghatches.item.ItemFakePattern; import reobf.proghatches.item.ItemFixer; +import reobf.proghatches.item.ItemMEPlunger; import reobf.proghatches.item.ItemProgrammingCircuit; import reobf.proghatches.item.ItemProgrammingToolkit; import reobf.proghatches.item.ItemSmartArm; @@ -54,7 +55,9 @@ public void preInit(FMLPreInitializationEvent event) { GameRegistry.registerTileEntity(TileCoprocessor.class, "proghatches.coprocessor"); GameRegistry.registerTileEntity(TileFluidInterface_EU.class, "proghatches.euinterface"); - + GameRegistry.registerItem( + MyMod.plunger = new ItemMEPlunger(100000).setUnlocalizedName("proghatch_me_plunger").setTextureName("proghatches:plunger"), + "proghatch_me_plunger"); GameRegistry.registerItem( MyMod.progcircuit = new ItemProgrammingCircuit().setUnlocalizedName("prog_circuit").setTextureName("?"), "prog_circuit"); diff --git a/src/main/java/reobf/proghatches/main/Config.java b/src/main/java/reobf/proghatches/main/Config.java index 2cc0ede..4d24290 100644 --- a/src/main/java/reobf/proghatches/main/Config.java +++ b/src/main/java/reobf/proghatches/main/Config.java @@ -31,7 +31,7 @@ public class Config { public static boolean experimentalOptimize=true; public static boolean sleep=true; public static boolean MECover=false; - + public static boolean delayUnlock=true; public static void synchronizeConfiguration(File configFile) { Configuration configuration = new Configuration(configFile); @@ -264,5 +264,6 @@ public static String[] get(String key, Map fmtter, boolean defau + } diff --git a/src/main/java/reobf/proghatches/main/MyMod.java b/src/main/java/reobf/proghatches/main/MyMod.java index 87256a1..eb66e59 100644 --- a/src/main/java/reobf/proghatches/main/MyMod.java +++ b/src/main/java/reobf/proghatches/main/MyMod.java @@ -147,6 +147,7 @@ public class MyMod { public static Item book; public static Item fixer; //public static Item eu_tool; + public static Item plunger; @Mod.EventHandler // preInit "Run before anything else. Read your config, create blocks, @@ -169,7 +170,7 @@ public void init(FMLInitializationEvent event) { FMLCommonHandler.instance().bus().register(this); MinecraftForge.EVENT_BUS.register(this); } - + @SubscribeEvent public void overrideTutorialBookClickBehaviour(PlayerInteractEvent ev) { if (Optional.ofNullable(ev.entityPlayer.getHeldItem()).map(ItemStack::getItem) diff --git a/src/main/java/reobf/proghatches/main/asm/AEItemTransformer.java b/src/main/java/reobf/proghatches/main/asm/AEItemTransformer.java new file mode 100644 index 0000000..b3cb017 --- /dev/null +++ b/src/main/java/reobf/proghatches/main/asm/AEItemTransformer.java @@ -0,0 +1,58 @@ +package reobf.proghatches.main.asm; + + + + + +import java.io.File; +import java.io.FileOutputStream; + + + + +import net.minecraft.launchwrapper.IClassTransformer; +import reobf.proghatches.main.asm.repack.objectwebasm.ClassReader; +import reobf.proghatches.main.asm.repack.objectwebasm.ClassWriter; + +public class AEItemTransformer implements IClassTransformer { + boolean done; + + @SuppressWarnings("unused") + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) { + + if ((!done) && name.equals("reobf.proghatches.item.ItemMEPlunger")) { + done = true; + + + + //asm for java17 is not working(for me)! + //so I packed one copy of asm for java8 + ClassReader cr = null; + cr = new ClassReader(basicClass); + cr.getSuperName(); + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES) { + + + @Override + public int newUTF8(String value) { + + if (value.contains("reobf/proghatches/item/DummySuper")) { + return super.newUTF8(value.replace( + "reobf/proghatches/item/DummySuper", + + "appeng/items/tools/powered/powersink/AEBasePoweredItem")); + } + return super.newUTF8(value); + } + + }; + + cr.accept(cw, 0); + + return cw.toByteArray(); + + } + return basicClass; + } +} diff --git a/src/main/java/reobf/proghatches/main/asm/FMLPlugin.java b/src/main/java/reobf/proghatches/main/asm/FMLPlugin.java index 5333838..9704cad 100644 --- a/src/main/java/reobf/proghatches/main/asm/FMLPlugin.java +++ b/src/main/java/reobf/proghatches/main/asm/FMLPlugin.java @@ -15,7 +15,10 @@ public class FMLPlugin implements IEarlyMixinLoader, IFMLLoadingPlugin { @Override public String[] getASMTransformerClass() { System.out.println("xxxxxxxxxxxxxxxx"); - return new String[] { EUInterfaceTransformer.class.getName() }; + return new String[] { + EUInterfaceTransformer.class.getName() , + AEItemTransformer.class.getName() , + }; } @Override diff --git a/src/main/java/reobf/proghatches/main/mixin/MixinCallback.java b/src/main/java/reobf/proghatches/main/mixin/MixinCallback.java index 291b0ec..0fec76a 100644 --- a/src/main/java/reobf/proghatches/main/mixin/MixinCallback.java +++ b/src/main/java/reobf/proghatches/main/mixin/MixinCallback.java @@ -1,14 +1,37 @@ package reobf.proghatches.main.mixin; import java.lang.reflect.Field; +import java.util.LinkedList; +import java.util.Map; +import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Function; + +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import appeng.api.config.Actionable; +import appeng.api.config.FuzzyMode; +import appeng.api.networking.crafting.ICraftingPatternDetails; +import appeng.api.networking.energy.IEnergyGrid; +import appeng.api.networking.security.MachineSource; +import appeng.api.storage.data.IAEItemStack; +import appeng.crafting.MECraftingInventory; +import appeng.me.cache.CraftingGridCache; +import appeng.tile.crafting.TileCraftingTile; +import appeng.util.item.AEItemStack; import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase; import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.MinecraftServer; +import reobf.proghatches.eucrafting.IEUManager; +import reobf.proghatches.eucrafting.IEUManager.EUManager; +import reobf.proghatches.eucrafting.TileFluidInterface_EU.SISOPatternDetail; import reobf.proghatches.gt.metatileentity.DualInputHatch; +import reobf.proghatches.main.MyMod; +import reobf.proghatches.util.ProghatchesUtil; public class MixinCallback { @@ -94,4 +117,97 @@ public static boolean fixCircuitTag(NBTTagCompound stackTagCompound){ return false; } -} + +private static AEItemStack type = AEItemStack.create(new ItemStack(MyMod.eu_token, 1, 1)); +public static void cb(final IEnergyGrid eg, final CraftingGridCache cc, CallbackInfo RE + ,Map needed + ,Map storage + ,MECraftingInventory inventory, + Map tasks, + LinkedList tiles, + MachineSource machineSrc + ) { + try{ + if (needed.isEmpty()) { + storage.clear(); + return; + } + + + + inventory.getItemList().findFuzzy(type, FuzzyMode.IGNORE_ALL).forEach(s -> { + + if (s.getItem() == MyMod.eu_token) { + if (s.getItemDamage() == 1) { + + IAEItemStack u = s.copy().setStackSize(1); + + storage.merge(u, s.getStackSize(), Long::sum); + } + + } + + }); + System.out.println(storage); + tasks.entrySet().forEach(s -> { + // TODO remove + + if (s.getKey() instanceof SISOPatternDetail) { + SISOPatternDetail d = (SISOPatternDetail) s.getKey(); + if (d.out.getItemDamage() == 1) { + IAEItemStack key = d.o[0].copy().setStackSize(1); + + storage.merge(key, MixinCallback.getter.apply(s.getValue()), Long::sum); + + } + + } + + }); + System.out.println(storage); + System.out.println(needed); + + needed.entrySet().forEach(s -> { + + long num = Optional.ofNullable(storage.get(s.getKey())).orElse(0l); + long missing = s.getValue() - num; + if (missing <= 0) + return; + // Object o=this; + // CraftingCPUCluster thiz=(CraftingCPUCluster) o; + // System.out.println(s.getValue()+" "+num); + // System.out.println(missing); + + if (tiles.isEmpty()) { + return; + } + try { + EUManager man = tiles.get(0).getProxy().getGrid().getCache(IEUManager.class); + long get = man.request(s.getKey().getTagCompound().getNBTTagCompoundCopy().getLong("voltage"), missing); + if(get>0){ + + inventory.injectItems(s.getKey().copy().setStackSize(get), Actionable.MODULATE, machineSrc); + man.cache.get(s.getKey().getTagCompound().getNBTTagCompoundCopy().getLong("voltage")) + .stream().filter(sp->sp.getUUID().equals(ProghatchesUtil.deser(s.getKey().getTagCompound().getNBTTagCompoundCopy(), "EUFI"))) + .findFirst().get().refund(-get); + ; + MyMod.LOG.info("Auto Request:" + get + "*" + s.getKey().getTagCompound().getNBTTagCompoundCopy()); + MyMod.LOG.info(MinecraftServer.getServer().getTickCounter()); + //MyMod.LOG.info(MinecraftServer.getServer().getTickCounter()); + } + } catch (Exception e) { + + e.printStackTrace(); + } + + /* + */ + + }); + + storage.clear(); + needed.clear(); + }catch(Exception e){MyMod.LOG.error("caught error in mixin",e);} +}} + + diff --git a/src/main/java/reobf/proghatches/main/mixin/mixins/eucrafting/MixinCpuClusterEUAutoRequest.java b/src/main/java/reobf/proghatches/main/mixin/mixins/eucrafting/MixinCpuClusterEUAutoRequest.java index 720c91d..5d39646 100644 --- a/src/main/java/reobf/proghatches/main/mixin/mixins/eucrafting/MixinCpuClusterEUAutoRequest.java +++ b/src/main/java/reobf/proghatches/main/mixin/mixins/eucrafting/MixinCpuClusterEUAutoRequest.java @@ -23,11 +23,16 @@ import appeng.tile.crafting.TileCraftingTile; import appeng.util.item.AEItemStack; import net.minecraft.item.ItemStack; +import net.minecraft.server.MinecraftServer; +import reobf.proghatches.eucrafting.EUUtil; import reobf.proghatches.eucrafting.IEUManager; +import reobf.proghatches.eucrafting.ItemEUToken; +import reobf.proghatches.eucrafting.IEUManager.EUManager; import reobf.proghatches.eucrafting.TileFluidInterface_EU.SISOPatternDetail; import reobf.proghatches.eucrafting.TileFluidInterface_EU.WrappedPatternDetail; import reobf.proghatches.main.MyMod; import reobf.proghatches.main.mixin.MixinCallback; +import reobf.proghatches.util.ProghatchesUtil; @Mixin(value = CraftingCPUCluster.class, remap = false, priority = 0) public abstract class MixinCpuClusterEUAutoRequest { @@ -82,7 +87,8 @@ private ICraftingPatternDetails executeCrafting2(ICraftingPatternDetails pattern } if (isOnlyEUTokenMissing) { - needed.put(p.extraIn.copy().setStackSize(1), p.extraIn0.stackSize + 0l); + long exist=needed.getOrDefault(p.extraIn.copy().setStackSize(1), 0l); + if(exist==0)needed.put(p.extraIn.copy().setStackSize(1), p.extraIn0.stackSize + 0l); cooldown.remove(p); } else { cooldown.get(p)[0] += Math.min((10 + 2 * cooldown.get(p)[1]++), 100); @@ -96,92 +102,20 @@ private ICraftingPatternDetails executeCrafting2(ICraftingPatternDetails pattern }catch(Exception e){MyMod.LOG.error("caught error in mixin",e);} return pattern; } - +/* @Inject(at = @At("HEAD"), method = "executeCrafting", cancellable = true) private void executeCrafting3(final IEnergyGrid eg, final CraftingGridCache cc, CallbackInfo RE) { } - +*/ private static AEItemStack type = AEItemStack.create(new ItemStack(MyMod.eu_token, 1, 1)); @Inject(at = @At("RETURN"), method = "executeCrafting", cancellable = true) private void executeCrafting1(final IEnergyGrid eg, final CraftingGridCache cc, CallbackInfo RE) { - try{ - if (needed.isEmpty()) { - storage.clear(); - return; - } - - // ArrayList arr=new ArrayList(); - - // inventory.getItemList().forEach(arr::add); - // System.out.println(arr); - - inventory.getItemList().findFuzzy(type, FuzzyMode.IGNORE_ALL).forEach(s -> { - - if (s.getItem() == MyMod.eu_token) { - if (s.getItemDamage() == 1) { - - IAEItemStack u = s.copy().setStackSize(1); - - storage.merge(u, s.getStackSize(), Long::sum); - } - - } - - }); - - tasks.entrySet().forEach(s -> { - // TODO remove - - if (s.getKey() instanceof SISOPatternDetail) { - SISOPatternDetail d = (SISOPatternDetail) s.getKey(); - if (d.out.getItemDamage() == 1) { - IAEItemStack key = d.o[0].copy().setStackSize(1); - - storage.merge(key, MixinCallback.getter.apply(s.getValue()), Long::sum); - - } - - } - - }); - // System.out.println(storage); - - needed.entrySet().forEach(s -> { - - long num = Optional.ofNullable(storage.get(s.getKey())).orElse(0l); - long missing = s.getValue() - num; - if (missing <= 0) - return; - // Object o=this; - // CraftingCPUCluster thiz=(CraftingCPUCluster) o; - // System.out.println(s.getValue()+" "+num); - // System.out.println(missing); - - if (tiles.isEmpty()) { - return; - } - try { - IEUManager man = tiles.get(0).getProxy().getGrid().getCache(IEUManager.class); - long get = man.request(s.getKey().getTagCompound().getNBTTagCompoundCopy().getLong("voltage"), missing); - - inventory.injectItems(s.getKey().copy().setStackSize(get), Actionable.MODULATE, machineSrc); - MyMod.LOG.info("Auto Request:" + get + "*" + s.getKey().getTagCompound().getNBTTagCompoundCopy()); - - } catch (Exception e) { - - e.printStackTrace(); - } - - /* - */ - - }); - - storage.clear(); - needed.clear(); - }catch(Exception e){MyMod.LOG.error("caught error in mixin",e);} + + MixinCallback.cb(eg, cc, RE, needed, storage, inventory, tasks, tiles, machineSrc); + + } } diff --git a/src/main/java/reobf/proghatches/main/mixin/mixins/eucrafting/MixinMachineIdle2.java b/src/main/java/reobf/proghatches/main/mixin/mixins/eucrafting/MixinMachineIdle2.java index aebd120..bd533b7 100644 --- a/src/main/java/reobf/proghatches/main/mixin/mixins/eucrafting/MixinMachineIdle2.java +++ b/src/main/java/reobf/proghatches/main/mixin/mixins/eucrafting/MixinMachineIdle2.java @@ -6,6 +6,7 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; @@ -17,46 +18,52 @@ @Mixin(value=GT_MetaTileEntity_BasicMachine.class,remap=false) -public class MixinMachineIdle2 implements IIdleStateProvider{ -private boolean hasJob; -@Shadow int mMaxProgresstime; +public abstract class MixinMachineIdle2 implements IIdleStateProvider{ +@Shadow int mMaxProgresstime; +boolean fail; public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - hasJob=mMaxProgresstime>0; - if(jobdone>0)jobdone--; - fail=false; + a(aBaseMetaTileEntity);fail=false; } -int jobdone; - + - @Inject(remap=false,method="checkRecipe", at = { @At("RETURN") }) - public void check(CallbackInfoReturnable c){ - - if(hasJob&&!(mMaxProgresstime>0)){ - jobdone=1; - } - if(!(mMaxProgresstime>0)){ - - fail=true; - } + @Inject(remap=false,method="onPostTick", at = { @At("RETURN") }) + public void check(IGregTechTileEntity aBaseMetaTileEntity, long aTick,CallbackInfo p){ + if(shouldCheck&&mMaxProgresstime<=0){fail=true;} } -boolean fail; @Override -public int getIdle() { - return jobdone; -} - + public boolean failThisTick() { + + return fail; + } -@Override -public boolean failThisTick() { - return fail; -} +@Shadow +public abstract boolean allowToCheckRecipe(); +@Shadow +protected abstract boolean hasEnoughEnergyToCheckRecipe(); +public void a(IGregTechTileEntity aBaseMetaTileEntity){ + shouldCheck=false; + if (allowToCheckRecipe()) { + if (mMaxProgresstime <= 0 && aBaseMetaTileEntity.isAllowedToWork() + /*&& (tRemovedOutputFluid || tSucceeded + || aBaseMetaTileEntity.hasInventoryBeenModified() + || aTick % 600 == 0 + || aBaseMetaTileEntity.hasWorkJustBeenEnabled())*/ + && hasEnoughEnergyToCheckRecipe()) { + + + shouldCheck=true; + } + + } +} +boolean shouldCheck; } diff --git a/src/main/java/reobf/proghatches/main/registration/PHRecipes.java b/src/main/java/reobf/proghatches/main/registration/PHRecipes.java index fc5ffd1..b8b1fe5 100644 --- a/src/main/java/reobf/proghatches/main/registration/PHRecipes.java +++ b/src/main/java/reobf/proghatches/main/registration/PHRecipes.java @@ -15,14 +15,19 @@ import java.util.Map; import java.util.Optional; +import net.minecraft.block.Block; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.IRecipe; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.oredict.OreDictionary; +import net.minecraftforge.oredict.ShapedOreRecipe; + import com.glodblock.github.loader.ItemAndBlockHolder; import appeng.core.Api; @@ -94,6 +99,39 @@ public void run() { if(Config.skipRecipeAdding)return; + +IRecipe rec = new ShapedOreRecipe(new ItemStack(MyMod.plunger),"CRR","TSR","Q F", + 'R',"plateAnyRubber", + 'C',"craftingToolWireCutter", + 'F',"craftingToolFile", + 'Q',"stickCertusQuartz", + 'S', + new ItemStack( + GameRegistry.findItem("appliedenergistics2","item.ToolChargedStaff"),1, + OreDictionary.WILDCARD_VALUE + ) + + //Api.INSTANCE.definitions().items().chargedStaff().maybeStack(1).get() + //ApiItems.chargedStaff() returns memoryCard, not chargedStaff + //What are you doing GTNH dev? + + , + 'T', + + new ItemStack( + GameRegistry.findItem("appliedenergistics2","item.ToolWirelessTerminal"),1, + OreDictionary.WILDCARD_VALUE + ) + + ); +CraftingManager.getInstance().getRecipeList().add(rec); + + + + + + + ArrayList pc0 = new ArrayList<>(); HashMapproductivity */> pc = new HashMap<>();// List> diff --git a/src/main/java/reobf/proghatches/main/registration/ProgHatchCreativeTab.java b/src/main/java/reobf/proghatches/main/registration/ProgHatchCreativeTab.java index 9cd0e0c..7671378 100644 --- a/src/main/java/reobf/proghatches/main/registration/ProgHatchCreativeTab.java +++ b/src/main/java/reobf/proghatches/main/registration/ProgHatchCreativeTab.java @@ -47,6 +47,7 @@ public void displayAllReleventItems(List p_78018_1_) { p_78018_1_.add(new ItemStack(MyMod.iohub, 1)); p_78018_1_.add(new ItemStack(MyMod.pitem, 1)); p_78018_1_.add(new ItemStack(MyMod.pstation, 1)); + p_78018_1_.add(new ItemStack(MyMod.plunger, 1)); // p_78018_1_.add(new ItemStack(MyMod.euupgrade, 1)); } diff --git a/src/main/resources/assets/proghatches/lang/en_US.lang b/src/main/resources/assets/proghatches/lang/en_US.lang index cedb761..f707852 100644 --- a/src/main/resources/assets/proghatches/lang/en_US.lang +++ b/src/main/resources/assets/proghatches/lang/en_US.lang @@ -383,3 +383,11 @@ item.proghatches.part.eu.source.superconduct.name=EU Source(%s Superconducting) item.proghatches.part.eu.source.normal.name=EU Source(%s) programmable_hatches.gt.sticky.autounlock=Auto disable sticky mode when empty. programmable_hatches.gt.phantom.filter=Filter +item.proghatch_me_plunger.name=ME Plunger +item.proghatch_me_plunger.unbound=Security Terminal missing. +item.proghatch_me_plunger.range=Signal out of range. +item.proghatch_me_plunger.tooltips.0=Clear items from pipe into ME Storage. +item.proghatch_me_plunger.tooltips.1=Clear fluid from tank into ME Storage. +item.proghatch_me_plunger.tooltips.2=Clear contents in buffers of Dual Hatch into ME Storage. +item.proghatch_me_plunger.tooltips.3=No not affect essentia. +item.proghatch_me_plunger.tooltips=4 diff --git a/src/main/resources/assets/proghatches/lang/zh_CN.lang b/src/main/resources/assets/proghatches/lang/zh_CN.lang index 9c38382..0376107 100644 --- a/src/main/resources/assets/proghatches/lang/zh_CN.lang +++ b/src/main/resources/assets/proghatches/lang/zh_CN.lang @@ -235,38 +235,25 @@ item.proghatch.cover.dedicated.tooltips.2.4=红石线无法传递1tick脉冲?试 item.proghatch.cover.dedicated.tooltips.2=5 itemGroup.proghatches.eucrafting=可编程仓室|EU合成 item.proghatches.euinterface.p2p.name=P2P - EU接口 -proghatches.eucreafting.finish.false=等待红石脉冲... +proghatches.eucreafting.finish.false=点击强制释放封包 proghatches.eucreafting.finish.true=准备归还电流封包 proghatches.eucreafting.p2p.connection=无法访问输入端 programmable_hatches.eucreafting.tutorial.pages.0=EU合成套件致力于通过按需供电,并在供能不足时阻塞配方,解决前期在耗电峰值瞬间导致的跳电问题。 -programmable_hatches.eucreafting.tutorial.pages.1=电流封包\n\n一个电流封包代表了某个电压的1A电流,用来加在样板输入中,从而在供能不足时阻止原料的发配,并不是真实GTEU的等价物也不能直接转换成GTEU -programmable_hatches.eucreafting.tutorial.pages.2=EU源\n\n真实GTEU输入ME网络的入口。能直接连接电缆或动力仓。\n连入ME网络后,你能在终端看到电流封包的合成,但不能(也不应该)通过合成终端手动下单,它只能被合成系统自动请求。 -programmable_hatches.eucreafting.tutorial.pages.3=右键打开GUI以设置其期望电压与期望电流。代表这个EU源所连接电源的供能能力。每被合成系统请求一个对应电压的封包,EU源就能向ME网络提供1A电流,最多提供<期望电流>A的电流。 -programmable_hatches.eucreafting.tutorial.pages.4=合成CPU在合成完毕后会将电流封包退回ME存储,EU源会回收ME存储内的封包,释放被占用的电流。 -programmable_hatches.eucreafting.tutorial.pages.5=EU接口\n\n二合一接口,兼任GTEU的输出口。除了二合一接口本身的功能,它还能连接电缆,从ME网络接收GTEU为GT机器供电。\nshift+右键打开EU接口配置GUI(不按shift打开二合一接口GUI) -programmable_hatches.eucreafting.tutorial.pages.6=设定期望电压和期望电流,合成时它会从对应电压的EU源请求封包以提取GTEU,如果没有空闲的EU源以提供封包,配方会被阻塞。 -programmable_hatches.eucreafting.tutorial.pages.7=电流封包(绑定)\n\n绑定到某个特定EU接口的电流封包,记录了EU接口的UUID,被EU源回收时会释放对应EU接口占用的电流。 -programmable_hatches.eucreafting.tutorial.pages.8=它是如何工作的?\nEU源会提供一个虚拟的样板,其输入为空输出为一个电流封包,记为样板①。配置过的EU接口会提供一个虚拟的样板,其输入为一个电流封包输出为一个电流封包(绑定),记为样板②。 -programmable_hatches.eucreafting.tutorial.pages.9=同时EU接口还会为每个插入的编码样板输入输出各添加<期望电流>个电流封包(绑定),假设有两个实际样板,记为样板③Ⅰ,③Ⅱ。 -programmable_hatches.eucreafting.tutorial.pages.10=这样,对于期望电流是M的EU接口,在合成终端下单X个样板③Ⅰ和Y个样板③Ⅱ时,合成系统就会计算出形如\nM*①->M*②->\n③Ⅰ->...X个③Ⅰ..->③Ⅰ->\n③Ⅱ->...Y个③Ⅱ..->③Ⅱ的合成树。 -programmable_hatches.eucreafting.tutorial.pages.11=由于③的输入输出都包含M个电流封包(绑定),封包只需要合成M个,前一个样板的输出就能被作为后面一个的输入。电流封包(绑定)绑定了UUID,不同接口所用的电流封包(绑定)不会被认为是同一种物品,会各自申请封包。 -programmable_hatches.eucreafting.tutorial.pages.12=当样板③的输入被提交到EU接口,其中的电流封包(绑定)会被立刻送回合成CPU,其余原料会被正常发配。此时EU接口就会根据电流封包(绑定)的个数从EU源提取对应安培数的GTEU了。仅记录单次样板的电流封包(绑定)个数,重复发配不叠加。 -programmable_hatches.eucreafting.tutorial.pages.13=此外,不同于常规样板输入足够就会发配,虚拟样板①和②的发配是惰性执行的,仅在③除了封包外所有材料都齐全时才会实际被执行。 -programmable_hatches.eucreafting.tutorial.pages.14=不用理会合成计算器显示的封包合成数量(那个是错误的)。实际只需要足够供单EU接口的电流即可。 -programmable_hatches.eucreafting.tutorial.pages.15=提高效率--让渡封包\n\n如果一个样板的输入依赖另一个很慢的配方,那么发配一次后空闲时占据的电流封包就被浪费了。因此,为了解决这个问题,对EU接口产生一个红石信号下降沿就能使其让渡电流封包使用权。无需担心,输入材料再次就绪后会重新自动申请封包。 -programmable_hatches.eucreafting.tutorial.pages.16=P2P - EU接口\n\n升级版的P2P - 二合一接口 兼 面板形式的EU接口\n就像一个EU接口的每个面被单独拆开使用一样。需要用内存卡指定一个输出以及多个输出。输出端共享输入端的样板,也能和输入端一样输出电流。与P2P-ME接口一样,只能合成获取,无法被"调谐"。 -programmable_hatches.eucreafting.tutorial.pages.17=P2P-EU接口将输入端和所有输出端红石信号取 或运算 后的下降沿作为让渡信号,也就是说,只会在所有P2P的红石信号都下降后再让渡,可以同时与多台机器同时运作。 -programmable_hatches.eucreafting.tutorial.pages.18=忙碌检测覆盖板\n\n特化版的机器活跃检测覆盖板\n检测频率为1tick,机器完成工作时产生红石下降沿送给EU接口,即使让渡封包。 -programmable_hatches.eucreafting.tutorial.pages.19=如果使用单个EU接口(或者一组配对的P2P - EU接口)同时为多个独立的多方块机器提供合成,需要注意:大机器并不是每tick都查找配方,因此当某个大机器先查找了配方并立刻做完,会导致触发下降沿提前让渡电流,导致其他大机器开机跳电。 -programmable_hatches.eucreafting.tutorial.pages.20=解决方法1是开启忙碌检测覆盖板的"检测输入是否非空",那么实际红石信号将是(输入仓不为空||输入总线不为空||机器在工作),从而在机器不检测的tick也能补上红石信号,缺点是如果有实体电路/透镜则无法工作 -programmable_hatches.eucreafting.tutorial.pages.21=解决方法2是开启忙碌检测覆盖板的"保持信号5s",因为大机器检测间隔最大5s,将信号延时5s就能补齐不检测的真空期,缺点是速度慢,因为让渡也延时了5s -programmable_hatches.eucreafting.tutorial.pages.22=提醒:这些信号的最小频率是1tick,而非1红石刻(2tick),1tick的红石信号无法被原版红石元件传递!试试红石导管,红石p2p或者project red的红石合金丝吧,这些的响应速度都是1tick的 -programmable_hatches.eucreafting.tutorial.pages.23=ME接口覆盖板/ME二合一接口覆盖板\n\n覆盖板版本的ME接口,贴上覆盖板后,这个面就能连接ME线缆接入网络。每个面的覆盖板所属的网络是独立的,如果一个GT机器贴了两个覆盖板,网络也不会穿过这个机器。\n发配的原料会进入被贴的机器,而不是覆盖板对面的机器。 -programmable_hatches.eucreafting.tutorial.pages.24=使用方法与面板形式的接口无异,但阉割了物品栏/流体栏,类似高版本的样板供应器。发配的物品会直接进入所贴的GT机器,但返还物品需要另想办法--因为覆盖板没有物品栏。 -programmable_hatches.eucreafting.tutorial.pages.25=P2P - ME接口覆盖板/ME二合一接口覆盖板\n\n这是它们的P2P版本\n它们可以和面板形式的P2P使用内存卡互联,但不能作为输入端,也就是说你至少要用一个面板形式的P2P。PS:从技术上说并不是不能做输入,但万一出bug了里面存的样板就会直接弄丢... -programmable_hatches.eucreafting.tutorial.pages.26=P2P - EU接口覆盖板\n\n顾名思义\n它还集成了活跃检测覆盖板功能,就是说你可以直接把它贴在机器主控上,它的配置界面需要不按shift的情况下右键打开。 -programmable_hatches.eucreafting.tutorial.pages.27=ME覆盖板\n\n允许ME频道穿过所贴的方块。\n自身可以连接ME线缆,安装后该方块上其余接口覆盖板也会被连入同一个ME网络。\n两个方块的相接面贴上ME覆盖板也能传递频道。\n最多传递8频道。 -programmable_hatches.eucreafting.tutorial.pages=28 +programmable_hatches.eucreafting.tutorial.pages.1=电流封包\n\n一个电流封包代表了某个电压的1A电流,用来加在样板输入中(不需要手动编写,后面会详细说明),从而在供能不足时阻止原料的发配,并不是真实GTEU的等价物,也不能直接转换成GTEU +programmable_hatches.eucreafting.tutorial.pages.2=EU源\n\n真实GTEU输入ME网络的入口。通常需要贴着电源,可以是动力仓或者电池箱,也能连接线缆。\n连入ME网络后,你能在终端看到电流封包的合成.每合成一个封包,EU源就允许从动力仓接受1A电流. +programmable_hatches.eucreafting.tutorial.pages.3=右键打开GUI以设置其期望电压与期望电流。代表这个EU源所连接电源的供能能力。合成的封包个数最大为<期望电流>,达到上限后合成会被阻塞,直到封包被回收. +programmable_hatches.eucreafting.tutorial.pages.4=EU接口\n\n二合一接口,兼任GTEU的输出口。使用螺丝刀打开EU配置界面,设置其期望电压与期望电流. +programmable_hatches.eucreafting.tutorial.pages.5=一旦期望电流不为0,EU接口会自动为其中样板的输入和输出各添加数个电流封包,其数量等于<期望电流>.因此,下单EU接口中的样板时,AE的合成系统会先请求EU源的封包,请求成功后这一部分电流被此EU接口独占,直到配方完成. +programmable_hatches.eucreafting.tutorial.pages.6=因为输入输出都有等量封包,封包数量是守恒的,EU封包在合成时实际被存储在合成CPU内部,在所有任务被完成后,CPU内部的物品会被全部退回ME存储,此时EU源会自动回收掉ME存储的封包,将电流让给其它任务. +programmable_hatches.eucreafting.tutorial.pages.7=提前返还电流&按需申请电流\n\n如果合成涉及了多个EU接口,当其中一个接口任务全部完成后其电流仍然会被占用浪费.将EU接口指向GT机器就能监视其状态,在机器配方检查失败时将会认为机器不再需要电流,将临时归还占用的封包(即使合成尚未完全结束).当合成再次需要电流,会自动向可用的EU源发起申请. +programmable_hatches.eucreafting.tutorial.pages.8=未被使用的封包会被自动退回,因此合成确认界面显示的电流不一定准确. +programmable_hatches.eucreafting.tutorial.pages.9=P2P - EU接口\n\n将单个EU接口的 发配物品/提供电流/监视GT机器 功能分离到不同位置,给多方块机器的能源仓,输入仓/总线,主控分别贴一个P2P并连接即可.这一点是EU接口难以做到的. +programmable_hatches.eucreafting.tutorial.pages.10=ME接口覆盖板/ME二合一接口覆盖板\n\n覆盖板版本的ME接口,贴上覆盖板后,这个面就能连接ME线缆接入网络。每个面的覆盖板所属的网络是独立的,如果一个GT机器贴了两个覆盖板,网络也不会穿过这个机器。\n发配的原料会进入被贴的机器,而不是覆盖板对面的机器。 +programmable_hatches.eucreafting.tutorial.pages.11=使用方法与面板形式的接口无异,但阉割了物品栏/流体栏,类似高版本的样板供应器。发配的物品会直接进入所贴的GT机器,但返还物品需要另想办法--因为覆盖板没有物品栏。 +programmable_hatches.eucreafting.tutorial.pages.12=P2P - ME接口覆盖板/ME二合一接口覆盖板\n\n这是它们的P2P版本\n它们可以和面板形式的P2P使用内存卡互联,但不能作为输入端,也就是说你至少要用一个面板形式的P2P。PS:从技术上说并不是不能做输入,但万一出bug了里面存的样板就会直接弄丢... +programmable_hatches.eucreafting.tutorial.pages.13=P2P - EU接口覆盖板\n\n顾名思义\n它还集成了活跃检测覆盖板功能,就是说你可以直接把它贴在机器主控上,它的配置界面需要不按shift的情况下右键打开。 +programmable_hatches.eucreafting.tutorial.pages.14=ME覆盖板\n\n允许ME频道穿过所贴的方块。\n自身可以连接ME线缆,安装后该方块上其余接口覆盖板也会被连入同一个ME网络。\n两个方块的相接面贴上ME覆盖板也能传递频道。\n最多传递8频道。 +programmable_hatches.eucreafting.tutorial.pages=15 programmable_hatches.eucreafting.tutorial=EU合成套件(WIP) proghatches.eu.interface.waila.UUID=UUID: %s proghatches.eu.interface.waila.UUID.out.0=输入P2P信息: @@ -420,3 +407,11 @@ item.proghatches.part.eu.source.superconduct.name=EU源(%s超导) item.proghatches.part.eu.source.normal.name=EU源(%s) programmable_hatches.gt.sticky.autounlock=容器为空时自动禁用粘性模式 programmable_hatches.gt.phantom.filter=过滤 +item.proghatch_me_plunger.name=ME搋子 +item.proghatch_me_plunger.unbound=未找到安全终端 +item.proghatch_me_plunger.range=信号超出范围 +item.proghatch_me_plunger.tooltips.0=清理管道内物品存入ME存储 +item.proghatch_me_plunger.tooltips.1=清理缸内流体存入ME存储 +item.proghatch_me_plunger.tooltips.2=清理二合一输入仓缓存存入ME存储 +item.proghatch_me_plunger.tooltips.3=不能清理源质 +item.proghatch_me_plunger.tooltips=4 diff --git a/src/main/resources/assets/proghatches/textures/items/plunger.png b/src/main/resources/assets/proghatches/textures/items/plunger.png new file mode 100644 index 0000000..a127fcc Binary files /dev/null and b/src/main/resources/assets/proghatches/textures/items/plunger.png differ