From 81c4644fe3898d43372da219b70dc049955bad57 Mon Sep 17 00:00:00 2001 From: reobf <2215595288@qq.com> Date: Fri, 12 Apr 2024 00:30:48 +0800 Subject: [PATCH] EU Crafting update --- build.gradle | 2 +- .../proghatches/eucrafting/IEUManager.java | 25 +++++- .../eucrafting/PartEUP2PInterface.java | 9 ++- .../proghatches/eucrafting/PartEUSource.java | 9 +++ .../eucrafting/TileFluidInterface_EU.java | 9 ++- .../gt/cover/RecipeCheckResultCover.java | 2 +- .../gt/cover/RecipeOutputAwarenessCover.java | 2 +- .../RecipeCheckResultDetector.java | 2 +- .../java/reobf/proghatches/main/MyMod.java | 2 +- .../proghatches/main/mixin/MixinPlugin.java | 16 ++-- .../MixinCpuClusterEUAutoRequest.java | 80 ++++++++++++++----- .../eucrafting/MixinRemoveExcessiveEU.java | 30 ++++--- .../registration/EUCraftingCreativeTab.java | 4 +- .../main/registration/Registration.java | 15 ++-- .../assets/proghatches/lang/zh_CN.lang | 64 ++++++++------- 15 files changed, 180 insertions(+), 91 deletions(-) diff --git a/build.gradle b/build.gradle index 37e85ac..bf4fa7d 100644 --- a/build.gradle +++ b/build.gradle @@ -372,7 +372,7 @@ catch (Exception ignored) { // Pulls version first from the VERSION env and then git tag String identifiedVersion = null -String versionOverride = '0.0.9' +String versionOverride = '0.0.10' 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 5ce145b..bd05a48 100644 --- a/src/main/java/reobf/proghatches/eucrafting/IEUManager.java +++ b/src/main/java/reobf/proghatches/eucrafting/IEUManager.java @@ -27,12 +27,14 @@ public interface IEUManager extends IGridCache{ public interface ISource{ public long getVoltage(); public void reset(); - /*public long request(long amp); - public void refund(long amp); - public long providing();*/ + + //directly get EU token + public long request(long packets); + } public void refund(UUID id,long amount); + public long request(long v,long packets); public interface IDrain{ public default boolean isP2POut(){return false;} public long getVoltage(); @@ -156,6 +158,23 @@ public void refund(UUID id, long amount) { + } + + + @Override + public long request(long v, long packets) { + long req=packets; + + for(ISource s:cache2){ + + if(s.getVoltage()!=v) continue; + packets-=s.request(packets); + if(packets==0)break; + }; + + + + return req-packets; } } diff --git a/src/main/java/reobf/proghatches/eucrafting/PartEUP2PInterface.java b/src/main/java/reobf/proghatches/eucrafting/PartEUP2PInterface.java index f4f825f..138c225 100644 --- a/src/main/java/reobf/proghatches/eucrafting/PartEUP2PInterface.java +++ b/src/main/java/reobf/proghatches/eucrafting/PartEUP2PInterface.java @@ -457,13 +457,13 @@ public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLastCall) if(refund(inv,store)){ - ((CraftingCPUCluster)cluster).addCrafting(new PatternDetail(blank_token.copy(), + /* ((CraftingCPUCluster)cluster).addCrafting(new PatternDetail(blank_token.copy(), token.copy()), prevamp); ((CraftingCPUCluster)cluster).addEmitable(AEItemStack.create(blank_token.copy()).setStackSize(prevamp)); - redstoneticks=0; + */redstoneticks=0; amp=0; break; } @@ -1416,6 +1416,9 @@ public void refund(long amp) { } - + @Override + public ItemStack getCrafterIcon() { + return new ItemStack(MyMod.euinterface_p2p); + } } diff --git a/src/main/java/reobf/proghatches/eucrafting/PartEUSource.java b/src/main/java/reobf/proghatches/eucrafting/PartEUSource.java index 5d9d610..58a5617 100644 --- a/src/main/java/reobf/proghatches/eucrafting/PartEUSource.java +++ b/src/main/java/reobf/proghatches/eucrafting/PartEUSource.java @@ -712,4 +712,13 @@ public ItemStack getCrafterIcon() { return new ItemStack(MyMod.eu_source_part).setStackDisplayName(this.voltage + "V"); } + @Override + public long request(long packets) { + long free=amp-consumed ; + long actual=Math.min(free, packets); + consumed+=actual; + + return actual; + } + } diff --git a/src/main/java/reobf/proghatches/eucrafting/TileFluidInterface_EU.java b/src/main/java/reobf/proghatches/eucrafting/TileFluidInterface_EU.java index 8529d7d..21eadcc 100644 --- a/src/main/java/reobf/proghatches/eucrafting/TileFluidInterface_EU.java +++ b/src/main/java/reobf/proghatches/eucrafting/TileFluidInterface_EU.java @@ -420,7 +420,7 @@ public int hashCode() { } - ICraftingPatternDetails original; + public final ICraftingPatternDetails original; public final IAEItemStack extraIn; public final IAEItemStack extraOut; public final ItemStack extraIn0; @@ -1072,7 +1072,8 @@ 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/gt/cover/RecipeCheckResultCover.java b/src/main/java/reobf/proghatches/gt/cover/RecipeCheckResultCover.java index d44c3f6..fd6ac15 100644 --- a/src/main/java/reobf/proghatches/gt/cover/RecipeCheckResultCover.java +++ b/src/main/java/reobf/proghatches/gt/cover/RecipeCheckResultCover.java @@ -23,7 +23,7 @@ import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.Fluid; import reobf.proghatches.gt.cover.WirelessControlCover.Data; - +@Deprecated public class RecipeCheckResultCover extends GT_CoverBehaviorBase { public RecipeCheckResultCover() { diff --git a/src/main/java/reobf/proghatches/gt/cover/RecipeOutputAwarenessCover.java b/src/main/java/reobf/proghatches/gt/cover/RecipeOutputAwarenessCover.java index d465cb3..e090ca2 100644 --- a/src/main/java/reobf/proghatches/gt/cover/RecipeOutputAwarenessCover.java +++ b/src/main/java/reobf/proghatches/gt/cover/RecipeOutputAwarenessCover.java @@ -9,7 +9,7 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.FluidStack; - +@Deprecated public class RecipeOutputAwarenessCover extends GT_CoverBehavior{ @Override public int getTickRate(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { diff --git a/src/main/java/reobf/proghatches/gt/metatileentity/RecipeCheckResultDetector.java b/src/main/java/reobf/proghatches/gt/metatileentity/RecipeCheckResultDetector.java index 9ff537a..bca155d 100644 --- a/src/main/java/reobf/proghatches/gt/metatileentity/RecipeCheckResultDetector.java +++ b/src/main/java/reobf/proghatches/gt/metatileentity/RecipeCheckResultDetector.java @@ -25,7 +25,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.ForgeDirection; import reobf.proghatches.main.registration.Registration; - +@Deprecated public class RecipeCheckResultDetector extends GT_MetaTileEntity_Hatch_InputBus implements IRecipeProcessingAwareHatch { diff --git a/src/main/java/reobf/proghatches/main/MyMod.java b/src/main/java/reobf/proghatches/main/MyMod.java index 6669f14..bd09251 100644 --- a/src/main/java/reobf/proghatches/main/MyMod.java +++ b/src/main/java/reobf/proghatches/main/MyMod.java @@ -72,7 +72,7 @@ public class MyMod { // preInit "Run before anything else. Read your config, create blocks, items, etc, and register them with the // GameRegistry." (Remove if not needed) public void preInit(FMLPreInitializationEvent event) { - CraftingCPUCluster.class.getFields(); + //CraftingCPUCluster.class.getFields(); net.registerMessage(new OpenPartGuiMessage.Handler(), OpenPartGuiMessage.class, 0, Side.CLIENT); proxy.preInit(event); } diff --git a/src/main/java/reobf/proghatches/main/mixin/MixinPlugin.java b/src/main/java/reobf/proghatches/main/mixin/MixinPlugin.java index d2c4994..5cf829e 100644 --- a/src/main/java/reobf/proghatches/main/mixin/MixinPlugin.java +++ b/src/main/java/reobf/proghatches/main/mixin/MixinPlugin.java @@ -57,11 +57,14 @@ public void acceptTargets(Set myTargets, Set otherTargets) { } String cfg= -"#set to true to disable those optional mixins if it breaks someting"+System.lineSeparator()+ +"#disable those optional mixins if it breaks someting"+System.lineSeparator()+ +"#set to true to disable otherwise apply"+System.lineSeparator()+ "noPatternEncodingMixin=false"+System.lineSeparator()+ "noFixTossBug=false"+System.lineSeparator()+ "noRecipeFilterForDualHatch=false"+System.lineSeparator()+ -"noRemoveUnusedCacheInModularUIContainer=fasle"+System.lineSeparator() +"noRemoveUnusedCacheInModularUIContainer=fasle"+System.lineSeparator()+ +"noFixRecursiveCraft=false"+System.lineSeparator()+ +"noEUCraftingMixins=false"+System.lineSeparator() ; @SuppressWarnings("unused") @Override @@ -105,13 +108,16 @@ public List getMixins() { ArrayList ret = new ArrayList<>(); ret.add("eucrafting."+"MixinWailaProvider"); - ret.add("eucrafting."+"MixinRecipeStateDetect"); - ret.add("eucrafting."+"MixinCpuClusterAccess"); + //ret.add("eucrafting."+"MixinRecipeStateDetect"); + // ret.add("eucrafting."+"MixinCpuClusterAccess"); + ret.add("eucrafting."+"MixinInstantComplete"); + if(!"true".equals(pp.get("noFixRecursiveCraft"))) ret.add("eucrafting."+"MixinCraftingRecursiveWorkaround"); + if(!"true".equals(pp.get("noEUCraftingMixins"))){ ret.add("eucrafting."+"MixinCpuClusterEUAutoRequest"); ret.add("eucrafting."+"MixinRemoveExcessiveEU"); - + } ret.add("MixinAwarenessForDualHatch"); if(!"true".equals(pp.get("noRemoveUnusedCacheInModularUIContainer"))) 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 1aecaa0..80db9e9 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 @@ -1,14 +1,18 @@ package reobf.proghatches.main.mixin.mixins.eucrafting; +import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.UUID; +import java.util.WeakHashMap; import java.util.function.Function; import java.util.stream.Collectors; @@ -29,6 +33,7 @@ import com.google.common.collect.ImmutableMap; 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.IActionHost; @@ -38,10 +43,12 @@ import appeng.crafting.v2.CraftingContext; import appeng.me.cache.CraftingGridCache; import appeng.me.cluster.implementations.CraftingCPUCluster; +import appeng.tile.crafting.TileCraftingTile; import appeng.util.item.AEItemStack; import appeng.util.item.HashBasedItemList; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import reobf.proghatches.eucrafting.IEUManager; import reobf.proghatches.eucrafting.TileFluidInterface_EU.PatternDetail; import reobf.proghatches.eucrafting.TileFluidInterface_EU.WrappedPatternDetail; import reobf.proghatches.main.MyMod; @@ -50,35 +57,42 @@ @Mixin(value = CraftingCPUCluster.class, remap = false, priority = 0) -public class MixinCpuClusterEUAutoRequest { +public abstract class MixinCpuClusterEUAutoRequest { @Shadow private MachineSource machineSrc; Map storage=new HashMap<>(); Map needed=new HashMap<>(); @Shadow private MECraftingInventory inventory; - + @Shadow private final LinkedList tiles = new LinkedList<>(); @Shadow Map tasks; - +private WeakHashMap cooldown=new WeakHashMap<>(); +@Shadow abstract boolean canCraft(final ICraftingPatternDetails details, final IAEItemStack[] condensedInputs) ; /** if (!this.canCraft(details, details.getCondensedInputs())) { //INJECT HERE Shift.BY.3 i.remove(); } */ - //collect failed WrappedPatternDetail + @ModifyVariable(at = @At(value="INVOKE",target="canCraft(Lappeng/api/networking/crafting/ICraftingPatternDetails;[Lappeng/api/storage/data/IAEItemStack;)Z" ,shift=Shift.BY,by=3),method = "executeCrafting") private ICraftingPatternDetails executeCrafting2(ICraftingPatternDetails pattern - ){ + ){//collect failed WrappedPatternDetail if(pattern instanceof WrappedPatternDetail){ WrappedPatternDetail p=(WrappedPatternDetail) pattern; + int cd[]=cooldown.computeIfAbsent(p, (s)->new int[1]); + if(cd[0]>0){cd[0]--;return pattern;} + boolean isOnlyEUTokenMissing=false; + //cannot craft, but original one can, means that only eu token is missing + if (this.canCraft(p.original, p.original.getCondensedInputs())) {isOnlyEUTokenMissing=true;} - - - - - needed.put(p.extraIn.copy(),p.extraIn0.stackSize+0l); - + if(isOnlyEUTokenMissing) + { + needed.put(p.extraIn.copy().setStackSize(1),p.extraIn0.stackSize+0l); + cooldown.remove(p); + } + else + cooldown.get(p)[0]+=20; } return pattern; @@ -91,38 +105,43 @@ private void executeCrafting3(final IEnergyGrid eg, final CraftingGridCache cc,C } - +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 ){ if(needed.isEmpty()){storage.clear();;return;} + //ArrayList arr=new ArrayList(); + + //inventory.getItemList().forEach(arr::add); + //System.out.println(arr); + -inventory.getItemList().forEach(s->{ +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); - if(storage.get(u)==null){storage.put(u, 0l);}; - storage.compute(u, (a,b)->b+s.getStackSize()); + + storage.merge(u,0l, (a,b)->a+b+s.getStackSize()); } } }); - +//System.out.println(storage); tasks.entrySet().forEach(s->{ if(s.getKey() instanceof PatternDetail){ PatternDetail d=(PatternDetail) s.getKey(); if(d.out.getItemDamage()==1){ + IAEItemStack key = d.o[0].copy().setStackSize(1); - - storage.computeIfPresent(d.o[0].copy().setStackSize(1), - (a,b)->b+MixinCallback.getter.apply(s.getValue()) + storage.merge(key, 0l, + (a,b)->a+b+MixinCallback.getter.apply(s.getValue()) ); } @@ -134,19 +153,36 @@ private void executeCrafting1(final IEnergyGrid eg, final CraftingGridCache cc,C }); +//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); - CraftingCPUCluster j; - inventory.injectItems( - s.getKey().copy().setStackSize(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 ); + } catch (Exception e) { + + e.printStackTrace(); + } + /* + */ }); diff --git a/src/main/java/reobf/proghatches/main/mixin/mixins/eucrafting/MixinRemoveExcessiveEU.java b/src/main/java/reobf/proghatches/main/mixin/mixins/eucrafting/MixinRemoveExcessiveEU.java index 341d019..9d836de 100644 --- a/src/main/java/reobf/proghatches/main/mixin/mixins/eucrafting/MixinRemoveExcessiveEU.java +++ b/src/main/java/reobf/proghatches/main/mixin/mixins/eucrafting/MixinRemoveExcessiveEU.java @@ -49,7 +49,8 @@ public void startCrafting(MECraftingInventory storage, ICraftingCPU rawCluster, try { - Map tasks=(Map) f.get(cluster); + @SuppressWarnings("unchecked") + Map tasks=(Map) f.get(cluster); Map num=new HashMap<>(); tasks.forEach((a,b)->{ @@ -67,11 +68,11 @@ public void startCrafting(MECraftingInventory storage, ICraftingCPU rawCluster, long actual=MixinCallback.getter.apply(d.getValue()); long excessive= actual-need; if(excessive<=0)return; - if(!tokill.containsKey(d.getKey()))tokill.put((PatternDetail) d.getKey(), 0l); - tokill.computeIfPresent((PatternDetail) d.getKey(), (aa,bb)->bb+excessive); + // if(!tokill.containsKey(d.getKey()))tokill.put((PatternDetail) d.getKey(), 0l); + tokill.merge((PatternDetail) d.getKey(),0l, (aa,bb)->aa+bb+excessive); return ; }); - // System.out.println(tokill); + HashMap killnum=new HashMap(); tokill.forEach((a,b)->{ tasks.computeIfPresent(a, @@ -82,8 +83,8 @@ public void startCrafting(MECraftingInventory storage, ICraftingCPU rawCluster, //killnum[0]+=b; IAEItemStack is=a.i[0].copy().setStackSize(1); - if(!killnum.containsKey(is)){killnum.put(is, 0l);} - killnum.computeIfPresent(is, (ax,bx)->bx+a.i[0].getStackSize()); + + killnum.merge(is,0l, (ax,bx)->ax+bx+a.i[0].getStackSize()*b); @@ -93,15 +94,18 @@ public void startCrafting(MECraftingInventory storage, ICraftingCPU rawCluster, ); }); + // HashSet<> = tokill.keySet().stream().map(S->S.i[0]).collect(Collectors.toCollection(HashSet::new)); tasks.forEach((a,b)->{ if(a instanceof CircuitProviderPatternDetial){ CircuitProviderPatternDetial w=(CircuitProviderPatternDetial) a; - + + + + if(killnum.containsKey(AEItemStack.create(w.out))){ - - + MixinCallback.setter.accept(b,MixinCallback.getter.apply(b)-killnum.get(AEItemStack.create(w.out))); @@ -113,9 +117,15 @@ public void startCrafting(MECraftingInventory storage, ICraftingCPU rawCluster, }); - + /* tasks.forEach((s,b)->{ + + System.out.println(s+" "+MixinCallback.getter.apply(b)); + + });*/ + // + // System.out.println(killnum.get(AEItemStack.create(w.out))); diff --git a/src/main/java/reobf/proghatches/main/registration/EUCraftingCreativeTab.java b/src/main/java/reobf/proghatches/main/registration/EUCraftingCreativeTab.java index 2ffec8a..e801b59 100644 --- a/src/main/java/reobf/proghatches/main/registration/EUCraftingCreativeTab.java +++ b/src/main/java/reobf/proghatches/main/registration/EUCraftingCreativeTab.java @@ -32,9 +32,9 @@ public void displayAllReleventItems(List p_78018_1_) { p_78018_1_.addAll(Registration.items_eucrafting); p_78018_1_.add(new ItemStack(MyMod.eu_source_part)); p_78018_1_.add(new ItemStack(MyMod.block_euinterface)); - p_78018_1_.add(new ItemStack(MyMod.cover, 1, 2)); + // p_78018_1_.add(new ItemStack(MyMod.cover, 1, 2)); p_78018_1_.add(new ItemStack(MyMod.euinterface_p2p)); - + p_78018_1_.add(new ItemStack(MyMod.cover, 1, 3)); super.displayAllReleventItems(p_78018_1_); } diff --git a/src/main/java/reobf/proghatches/main/registration/Registration.java b/src/main/java/reobf/proghatches/main/registration/Registration.java index 0f37442..859ccb3 100644 --- a/src/main/java/reobf/proghatches/main/registration/Registration.java +++ b/src/main/java/reobf/proghatches/main/registration/Registration.java @@ -49,7 +49,8 @@ public class Registration implements Runnable { public final static int FilterOffset = 74;// -77 private static final int RecipeCheckResultDetectorOffset = 78; - @Override + @SuppressWarnings("deprecation") + @Override public void run() { for (int i = 0; i < GT_Values.VN.length - 1; i++) { @@ -129,19 +130,19 @@ public void run() { TextureFactory.of(gregtech.api.enums.Textures.BlockIcons.OVERLAY_SCREEN_GLOW)), new WirelessControlCover()); //WIP - GregTech_API.registerCover( + /*GregTech_API.registerCover( new ItemStack(MyMod.cover, 1, 15), TextureFactory.of( MACHINE_CASINGS[1][0], TextureFactory.of(gregtech.api.enums.Textures.BlockIcons.OVERLAY_SCREEN_GLOW)), - new RecipeOutputAwarenessCover()); - GregTech_API.registerCover( + new RecipeOutputAwarenessCover());*/ + /* GregTech_API.registerCover( new ItemStack(MyMod.cover, 1, 2), TextureFactory.of( MACHINE_CASINGS[1][0], TextureFactory.of(gregtech.api.enums.Textures.BlockIcons.OVERLAY_SCREEN_GLOW)), - new RecipeCheckResultCover()); + new RecipeCheckResultCover());*/ GregTech_API.registerCover( new ItemStack(MyMod.cover, 1, 3), TextureFactory.of( @@ -218,11 +219,11 @@ public void run() { i, false); - new RecipeCheckResultDetector( + /* new RecipeCheckResultDetector( Config.metaTileEntityOffset + RecipeCheckResultDetectorOffset, "recipe_check_result_detector", LangManager.translateToLocal("recipe_check_result_detector.name"), - 0); + 0);*/ } diff --git a/src/main/resources/assets/proghatches/lang/zh_CN.lang b/src/main/resources/assets/proghatches/lang/zh_CN.lang index ad9fedc..637812d 100644 --- a/src/main/resources/assets/proghatches/lang/zh_CN.lang +++ b/src/main/resources/assets/proghatches/lang/zh_CN.lang @@ -115,19 +115,19 @@ programmable_hatches.cover.smart.probe=测试 programmable_hatches.cover.smart.probe.move=移动§4探针 item.prog_toolkit.name.tooltip.emptyinput=如果要自动化生产,请使用编程器电路提供器 programmable_hatches.tutorial=可编程仓室--从入门到精通 -programmable_hatches.tutorial.pages.0=编程器电路与编程器覆盖板\n\n编程器电路与编程器覆盖板的关系正如流体封包和封包解码器的关系。编程器电路记录了一个特定物品,编程器覆盖板会自动把这个物品写入虚拟电路板槽并移除编程器电路。这个机制旨在解决含有不消耗物品的合成自动化。 -programmable_hatches.tutorial.pages.1=你可以将编程器覆盖板贴在单方块机器或是输入总线上。本模组的一些仓室自带编程器覆盖板功能。你只需要将编程器电路写入AE2的样板中,就能在避免混配方的情况下用单个机器处理所有的配方。此外,编程器电路不止能设置编程电路(包括GT++与Bartworks的电路),铸模、模头和透镜等不消耗物品也能被覆盖板写入虚拟电路板槽。 -programmable_hatches.tutorial.pages.2=编程器电路提供器\n\n编程器电路提供器可以连入AE网络,占用一个频道。连入后向网络提供编程器电路的合成,其类型取决于其GUI中放置的物品。合成是免费(或者说不消耗AE能量以外的资源),瞬间完成,且不限数量(实际取决于你的并行核数)的。 -programmable_hatches.tutorial.pages.3=一个提供器只能提供一种编程器电路,所以你可能需要使用多个提供器。提供器GUI的格子不能通过NEI书签标记来指定,你需要把编程电路留在格子里,所以至少要做出一个实际的物品,也就是说你不能借此跳过某些复杂的催化剂生产。 -programmable_hatches.tutorial.pages.4=编程工具箱 MK.II\n\n玩家背包携此物品时,在样板终端使用NEI一键编码功能时,自动将不消耗物品(NC标志)转化为编程器电路以标记样板,而不是直接忽略它。暂不支持无线样板终端。 -programmable_hatches.tutorial.pages.5=不推荐同时携带多个工具箱,可能导致无法正常运作。shift右键可以切换模式,模式3中,如果配方不含NC物品,会补上一个空的编程器电路,这种空电路可以重置虚拟电路板槽,以免先前的非空编程器电路造成干扰混配方。此外,直接右键可以打开GUI手动生成编程器电路用于调试。 -programmable_hatches.tutorial.pages.6=编程二合一输入仓\n\n你也可以叫它编程输入总成,怎样都好\n自带编程覆盖板功能,带有类似样板输入总成的输入隔离。使用方法是连接开启阻挡模式的ME接口,配合带编程器电路的样板,就能用单个仓室在不混配方的情况下为机器提供多种配方的输入。 -programmable_hatches.tutorial.pages.7=缓存编程二合一输入仓\n\n如果不关心它的具体工作方式,你只需要知道使用方法和前面的基础版本完全一致(是的,你依然需要打开阻挡模式),只是更快,还能充分利用机器的并行。 -programmable_hatches.tutorial.pages.8=缓存版本的编程二合一输入仓,主GUI中的物品/流体称为“输入区”,机器只能访问“缓存区”种的材料。当缓存区没有锁定配方,AE会发配一组材料并被阻挡,这些原料会在下一tick被转移进入缓存区并记录锁定单组材料的内容。当输入区的内容和某个缓存区锁定的配方顺序与数量完全一致,会被瞬间转移到缓存区。 -programmable_hatches.tutorial.pages.9=这样,即使开启阻挡模式,AE发配完一组原料后,不会因为阻挡模式停止发配。因此只需要2tick就能将原料全部发配给机器待用(如果AE有足够多并行)。每个缓存区(进阶版的有多个)内部附带编程器覆盖板功能,且有4个额外的虚拟槽,用于处理含多个不消耗物品的配方。每个缓存区也是互相输入隔离的。 -programmable_hatches.tutorial.pages.10=注意,缓存编程二合一输入仓的输入区没有编程覆盖板功能(即使手动贴覆盖板也一样),输入区的虚拟电路板是方便九合一加工厂指定类型用的,被每个缓存区共享。缓存区的容量会在tooltips中标注,允许超出容量,但超出后该缓存区会停止工作。 -programmable_hatches.tutorial.pages.11=右上角的“电源”按钮控制机器是否向“缓存区”转移材料,你可以关掉它,然后手动塞入一份材料再打开,这样缓冲区才能正确记录你的配方。 -programmable_hatches.tutorial.pages.12=无线控制覆盖板&智能机械臂>高级无线红石卡\n\n这些物品所访问的都是GT高级无线红石系统,是的,它们不兼容基础版的GT无线红石。 +programmable_hatches.tutorial.pages.0=编程器电路与编程器覆盖板\n\n编程器电路与编程器覆盖板的关系正如流体封包和封包解码器的关系。编程器电路记录了一个特定物品,编程器覆盖板会自动把这个物品写入虚拟电路板槽并移除编程器电路。这个机制旨在解决含有不消耗物品的合成自动化。 +programmable_hatches.tutorial.pages.1=你可以将编程器覆盖板贴在单方块机器或是输入总线上。本模组的一些仓室自带编程器覆盖板功能。你只需要将编程器电路写入AE2的样板中,就能在避免混配方的情况下用单个机器处理所有的配方。此外,编程器电路不止能设置编程电路(包括GT++与Bartworks的电路),铸模、模头和透镜等不消耗物品也能被覆盖板写入虚拟电路板槽。 +programmable_hatches.tutorial.pages.2=编程器电路提供器\n\n编程器电路提供器可以连入AE网络,占用一个频道。连入后向网络提供编程器电路的合成,其类型取决于其GUI中放置的物品。合成是免费(或者说不消耗AE能量以外的资源),瞬间完成,且不限数量(实际取决于你的并行核数)的。 +programmable_hatches.tutorial.pages.3=一个提供器只能提供一种编程器电路,所以你可能需要使用多个提供器。提供器GUI的格子不能通过NEI书签标记来指定,你需要把编程电路留在格子里,所以至少要做出一个实际的物品,也就是说你不能借此跳过某些复杂的催化剂生产。 +programmable_hatches.tutorial.pages.4=编程工具箱 MK.II\n\n玩家背包携此物品时,在样板终端使用NEI一键编码功能时,自动将不消耗物品(NC标志)转化为编程器电路以标记样板,而不是直接忽略它。暂不支持无线样板终端。 +programmable_hatches.tutorial.pages.5=不推荐同时携带多个工具箱,可能导致无法正常运作。shift右键可以切换模式,模式3中,如果配方不含NC物品,会补上一个空的编程器电路,这种空电路可以重置虚拟电路板槽,以免先前的非空编程器电路造成干扰混配方。此外,直接右键可以打开GUI手动生成编程器电路用于调试。 +programmable_hatches.tutorial.pages.6=编程二合一输入仓\n\n你也可以叫它编程输入总成,怎样都好\n自带编程覆盖板功能,带有类似样板输入总成的输入隔离。使用方法是连接开启阻挡模式的ME接口,配合带编程器电路的样板,就能用单个仓室在不混配方的情况下为机器提供多种配方的输入。 +programmable_hatches.tutorial.pages.7=缓存编程二合一输入仓\n\n如果不关心它的具体工作方式,你只需要知道使用方法和前面的基础版本完全一致(是的,你依然需要打开阻挡模式),只是更快,还能充分利用机器的并行。 +programmable_hatches.tutorial.pages.8=缓存版本的编程二合一输入仓,主GUI中的物品/流体称为“输入区”,机器只能访问“缓存区”种的材料。当缓存区没有锁定配方,AE会发配一组材料并被阻挡,这些原料会在下一tick被转移进入缓存区并记录锁定单组材料的内容。当输入区的内容和某个缓存区锁定的配方顺序与数量完全一致,会被瞬间转移到缓存区。 +programmable_hatches.tutorial.pages.9=这样,即使开启阻挡模式,AE发配完一组原料后,不会因为阻挡模式停止发配。因此只需要2tick就能将原料全部发配给机器待用(如果AE有足够多并行)。每个缓存区(进阶版的有多个)内部附带编程器覆盖板功能,且有4个额外的虚拟槽,用于处理含多个不消耗物品的配方。每个缓存区也是互相输入隔离的。 +programmable_hatches.tutorial.pages.10=注意,缓存编程二合一输入仓的输入区没有编程覆盖板功能(即使手动贴覆盖板也一样),输入区的虚拟电路板是方便九合一加工厂指定类型用的,被每个缓存区共享。缓存区的容量会在tooltips中标注,允许超出容量,但超出后该缓存区会停止工作。 +programmable_hatches.tutorial.pages.11=右上角的“电源”按钮控制机器是否向“缓存区”转移材料,你可以关掉它,然后手动塞入一份材料再打开,这样缓冲区才能正确记录你的配方。 +programmable_hatches.tutorial.pages.12=无线控制覆盖板&智能机械臂>高级无线红石卡\n\n这些物品所访问的都是GT高级无线红石系统,是的,它们不兼容基础版的GT无线红石。 programmable_hatches.tutorial.pages=13 item.proghatch.cover.dedicated.tooltips.1.0=带有安全模式的红石接收覆盖板(内) item.proghatch.cover.dedicated.tooltips.1=1 @@ -237,23 +237,27 @@ item.proghatches.euinterface.p2p.name=P2P - EU接口 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电流,用于表示电流的需求和产能,实际能量传递由AE元件完成。 -programmable_hatches.eucreafting.tutorial.pages.2=EU源\n\n是GT电源接入ME网络的入口,以提供电流封包合成的方式,向ME网络提供GTEU\n右键打开GUI以设置其期望电压以及最大的电流提供能力\n每通过合成CPU请求一个电流封包,EU源就增加1A的电流提供能力。当封包请求数达到极限,再请求合成会被阻塞直到封包被回收。 -programmable_hatches.eucreafting.tutorial.pages.3=只要在ME存储中有对应电压的封包,EU源就会回收它。\n无需担心,如果合成尚未结束,电流封包实际存储在合成CPU中,在全部合成结束后才会进入ME存储网络。 -programmable_hatches.eucreafting.tutorial.pages.4=EU接口\n\n拥有二合一接口的所有功能,同时也能按需从EU源获取GTEU为GT机器供能\n右键打开二合一接口GUI,Shift+右键打开EU设置,同样需要设置期望电压和期望电流,这通常等于它所供能的能源仓(单仓1A,双仓4A)或单方块机器(通常是1A)的属性。 -programmable_hatches.eucreafting.tutorial.pages.5=设置完毕后,通过终端能观察到 电流封包(绑定)的合成,这个是用于将EU源提供的电流绑定到这个EU接口的。电流封包(绑定)记录了这个EU接口的UUID,不同EU接口产生的电流封包(绑定)的NBT标签是不同的,这是为了让ME合成系统不会混淆它们。 -programmable_hatches.eucreafting.tutorial.pages.6=此时放入编码样板,编码样板被EU接口读取后,向AE提供数据时输入和输出都会被加上N个电流封包(绑定),其中N数值上等于期望电流(样板本身不变)。实际合成时电流封包不会进入目标容器,而是立刻返回CPU内部存储,而EU接口会记录下样板中的封包数N,并从EU源提取N安培电流。 -programmable_hatches.eucreafting.tutorial.pages.7=最后,如果机器工作完毕,电流封包就会从CPU存储返回ME存储,从而被EU源回收,如果电流封包是绑定的,也会释放对应UUID的EU接口可提取的电流N. -programmable_hatches.eucreafting.tutorial.pages.8=忙碌检测覆盖版\n\n差不多是更新频率为1tick的设备活跃检测覆盖版\n如果一个EU接口对应的机器不是合成的瓶颈,那么当它空闲时,占据的电流封包就被浪费了。因此,为了解决这个问题,对EU接口产生一个红石信号下降沿就能使其让渡电流封包使用权。 -programmable_hatches.eucreafting.tutorial.pages.9=这个覆盖板就是被特化用来做这个事的。当机器从工作状态停机后它就会产生一个下降沿,将其传递给EU接口即可。 -programmable_hatches.eucreafting.tutorial.pages.10=P2P - EU接口\n\nEU接口没有面板形式,因为没有GT仓室能同时从一个面交互物品、能量和红石信号。(尽管单方块机器能做到这一点)\nP2P - EU接口能解决这个问题,它的使用方式和P2P - ME二合一接口类似, -programmable_hatches.eucreafting.tutorial.pages.11=需要内存卡将一个输入绑定到多个输出,你可以从任一P2P输出能量,也会从任一P2P发配物品。Shift+右键P2P输入端打开EU设置GUI,输出端P2P没有独立的EU设置GUI,试图打开它会转跳到输入端。 -programmable_hatches.eucreafting.tutorial.pages.12=对于P2P - EU接口,其所有接口的红石信号求或后,产生的下降沿会让渡电流封包使用权。也就是说你也可以用它连接多个同类机器。但考虑到大机器并不是每tick都会检查配方,从而导致部分机器先行开动完成配方导致提前让渡,有两个不太优雅的解决方法: -programmable_hatches.eucreafting.tutorial.pages.13=1.开启忙碌检测覆盖版的保持信号5s功能\n大机器的最大检测间隔是5s,足够让其他大机器开工。缺点是会让让渡速度慢5s。 -programmable_hatches.eucreafting.tutorial.pages.14=2.开启忙碌检测覆盖版的检测输入是否非空功能\n即使机器没有开工,如果输入仓/总线非空也会发出红石信号。缺点是如果仓内有实体透镜/编程电路无法工作。\nPS:这个模式在小机器上无效果。 -programmable_hatches.eucreafting.tutorial.pages.15=特别说明:设置的电压实际上更类似于“频道”,不是真实的限制,最好但不必等于真实电压,EU合成系统也不会不加检查地将真实电压传递到EU接口。而设置的电流是真实的,EU源无法提供高于其期望电流的电流,即使实际电源供能能力更高,EU接口获取的电流不会高于期望电流,即使EU源提供的电流尚有盈余。 -programmable_hatches.eucreafting.tutorial.pages=16 +programmable_hatches.eucreafting.tutorial.pages.0=EU合成套件致力于通过按需供电,并在供能不足时阻塞配方,解决前期在耗电峰值瞬间导致的跳电问题。 +programmable_hatches.eucreafting.tutorial.pages.1=电流封包\n\n一个电流封包代表了某个电压的1A电流,以物品形式存在,利用AE合成机制来发配电流。不是真实的EU,是用来引导电流流向的工具 +programmable_hatches.eucreafting.tutorial.pages.2=EU源\n\n真实EU输入AE网络的入口。行为类似P2P-GTEU,能直接连接电缆或动力仓。\n连入ME网络后,你能在终端看到电流封包的合成。每”合成“一个电流封包,EU源就能向ME网络提供1A电流。 +programmable_hatches.eucreafting.tutorial.pages.3=打开GUI以设置其期望电压与期望电流。期望电压一般是它所连接的电源的电压等级,期望电流表示它一次性能提供的电流封包个数(一般为动力仓标称电流,电池箱等于电池个数A) +programmable_hatches.eucreafting.tutorial.pages.4=EU源会从ME存储中自动回收电流封包,从而自动释放被ME网络占用的电流。所以手动合成电流封包会立刻消失。 +programmable_hatches.eucreafting.tutorial.pages.5=EU接口\n\n一个升级版的二合一接口。除了二合一接口本身的功能,它还能连接电缆,从ME网络接收电流为GT机器供电。\n使用方法很简单,shift+右键打开EU配置(不按shift打开的是二合一接口) +programmable_hatches.eucreafting.tutorial.pages.6=设定期望电压和期望电流,合成时它会从对应电压的EU源请求封包以提取电流,在合成后自动释放。 +programmable_hatches.eucreafting.tutorial.pages.7=电流封包(绑定)\n\n绑定到某个特定EU接口的电流封包,记录了EU接口的UUID,代表此EU接口独占了EU源的1A电流。 +programmable_hatches.eucreafting.tutorial.pages.8=工作原理\nEU接口会给每个样板的输入和输出各添加N个电流封包(样板物品本身不变),这样无论在该EU接口请求多少该样板的合成,ME合成系统就只会请求N个电流封包(把前一个样板的封包输出,作为后一个样板的输入,只需要处理第一个样板的输入--从EU源请求) +programmable_hatches.eucreafting.tutorial.pages.9=电流封包在经过EU接口一次后,就会记录EU接口的UUID,成为电流封包(绑定),电流封包(绑定)不会被被其他UUID不一致的接口所使用。同时接口就会占用N安培电流,从EU源获电流了。 +programmable_hatches.eucreafting.tutorial.pages.10=正在合成时,材料实际上被保存在合成存储器内部而非ME存储,因此封包不会被EU源回收。合成完毕后,电流封包和电流封包(绑定)会返回ME存储从而被回收,电流封包(绑定)被回收时会释放对应EU接口占用的电流。 +programmable_hatches.eucreafting.tutorial.pages.11=由于EU源最大提供的封包数等于最大电流,所以供电能力不足时EU接口样板输入因为缺少所需的封包就会无法继续合成,从而阻止发配物品开机跳电,等封包被回收后,EU源就能继续提供封包。 +programmable_hatches.eucreafting.tutorial.pages.12=让渡封包\n\n如果在合成中一个EU接口对应的机器它空闲时,占据的电流封包就被浪费了。因此,为了解决这个问题,对EU接口产生一个红石信号下降沿就能使其让渡电流封包使用权。 +programmable_hatches.eucreafting.tutorial.pages.13=P2P - EU接口\n\n升级版的P2P - 二合一接口 兼 EU接口的面板形式\n就像一个EU接口的每个面被单独拆开使用一样。需要用内存卡指定一个输出以及多个输出。输出端共享输入端的样板,也能和输入端一样输出电流。它只能合成,与P2P-ME接口一样,无法被"调谐" +programmable_hatches.eucreafting.tutorial.pages.14=P2PEU接口让渡检测的红石信号是 输入端和所有输出端 红石信号取或后的下降沿,也就是说只会在所有红石信号都下降后再让渡,不用担心各个P2P各自为战 +programmable_hatches.eucreafting.tutorial.pages.15=忙碌检测覆盖版\n\n特化版的机器活跃检测覆盖版\n检测频率为1tick,机器完成工作时产生下降沿送给EU接口。 +programmable_hatches.eucreafting.tutorial.pages.16=如果使用单个EU接口(或者一组配对的P2P - EU接口)同时为多个独立的多方块机器提供合成,需要注意:大机器并不是每tick都查找配方,因此当某个大机器先查找了配方并立刻做完,会导致提取触发下降沿提前让渡电流,导致其他大机器开机跳电。 +programmable_hatches.eucreafting.tutorial.pages.17=解决方法1是开启忙碌检测覆盖版的"检测输入是否非空",那么实际红石信号将是(输入仓不为空||输入总线不为空||机器在工作),从而在机器不检测的tick也能补上红石信号,缺点是如果有实体电路/投机无法工作 +programmable_hatches.eucreafting.tutorial.pages.18=解决方法2是开启忙碌检测覆盖版的"保持信号5s",因为大机器检测间隔最大5s,将信号延时5s就能补齐不检测的真空期,缺点是速度慢,因为让渡也延时了5s +programmable_hatches.eucreafting.tutorial.pages.19=提醒:这些信号的最小频率是1tick,而非1红石刻(2tick),1tick的红石信号无法被原版红石元件传递!试试红石导管,红石p2p或者project red的红石合金丝吧,这些的响应速度都是1tick的 +programmable_hatches.eucreafting.tutorial.pages=20 programmable_hatches.eucreafting.tutorial=EU合成套件(WIP) proghatches.eu.interface.waila.UUID=UUID: %s proghatches.eu.interface.waila.UUID.out.0=输入P2P信息: