diff options
-rw-r--r-- | dependencies.gradle | 2 | ||||
-rw-r--r-- | src/main/java/net/glease/ggfab/mte/MTE_AdvAssLine.java | 173 | ||||
-rw-r--r-- | src/main/resources/assets/ggfab/lang/en_US.lang | 3 | ||||
-rw-r--r-- | src/main/resources/assets/ggfab/lang/zh_CN.lang | 28 |
4 files changed, 173 insertions, 33 deletions
diff --git a/dependencies.gradle b/dependencies.gradle index 011845387d..f425fd190c 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,7 +1,7 @@ // Add your dependencies here dependencies { - api("com.github.GTNewHorizons:GT5-Unofficial:5.09.43.26:dev") + api("com.github.GTNewHorizons:GT5-Unofficial:5.09.43.140:dev") testImplementation(platform('org.junit:junit-bom:5.8.2')) testImplementation('org.junit.jupiter:junit-jupiter') diff --git a/src/main/java/net/glease/ggfab/mte/MTE_AdvAssLine.java b/src/main/java/net/glease/ggfab/mte/MTE_AdvAssLine.java index 0083398dbd..0fba24f91b 100644 --- a/src/main/java/net/glease/ggfab/mte/MTE_AdvAssLine.java +++ b/src/main/java/net/glease/ggfab/mte/MTE_AdvAssLine.java @@ -5,6 +5,7 @@ import static gregtech.GT_Mod.GT_FML_LOGGER; import static gregtech.api.enums.GT_HatchElement.*; import static gregtech.api.enums.GT_Values.V; import static gregtech.api.enums.Textures.BlockIcons.casingTexturePages; +import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; import static gregtech.api.util.GT_StructureUtility.buildHatchAdder; import static gregtech.api.util.GT_StructureUtility.ofHatchAdder; import static net.glease.ggfab.BlockIcons.*; @@ -21,27 +22,41 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagInt; import net.minecraft.nbt.NBTTagList; +import net.minecraft.network.PacketBuffer; import net.minecraft.server.MinecraftServer; 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.Constants; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.FluidStack; +import org.jetbrains.annotations.NotNull; + import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; import com.gtnewhorizon.structurelib.structure.IStructureDefinition; import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; import com.gtnewhorizon.structurelib.structure.StructureDefinition; +import com.gtnewhorizons.modularui.api.drawable.IDrawable; +import com.gtnewhorizons.modularui.api.drawable.Text; +import com.gtnewhorizons.modularui.api.drawable.UITexture; +import com.gtnewhorizons.modularui.api.widget.ISyncedWidget; +import com.gtnewhorizons.modularui.api.widget.IWidgetBuilder; +import com.gtnewhorizons.modularui.api.widget.Widget; +import com.gtnewhorizons.modularui.common.widget.*; import gregtech.api.GregTech_API; import gregtech.api.enums.GT_Values; import gregtech.api.enums.ItemList; +import gregtech.api.enums.VoidingMode; import gregtech.api.interfaces.IHatchElement; import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.metatileentity.implementations.*; +import gregtech.api.recipe.check.CheckRecipeResult; +import gregtech.api.recipe.check.CheckRecipeResultRegistry; import gregtech.api.render.TextureFactory; import gregtech.api.util.*; import mcp.mobius.waila.api.IWailaConfigHandler; @@ -121,6 +136,7 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas private boolean stuck; private final ArrayList<GT_MetaTileEntity_Hatch_DataAccess> mDataAccessHatches = new ArrayList<>(); + private int currentInputLength; public MTE_AdvAssLine(int aID, String aName, String aNameRegional) { super(aID, aName, aNameRegional); @@ -271,11 +287,13 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas private void setCurrentRecipe(ItemStack stick, GT_Recipe.GT_Recipe_AssemblyLine recipe) { currentRecipe = recipe; currentStick = stick; + currentInputLength = recipe.mInputs.length; } private void clearCurrentRecipe() { currentRecipe = null; currentStick = null; + currentInputLength = -1; stuck = false; baseEUt = 0; for (Slice slice : slices) { @@ -296,7 +314,7 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas aNBT.setInteger("mRecipeHash", currentRecipe.getPersistentHash()); aNBT.setIntArray( TAG_KEY_PROGRESS_TIMES, - Arrays.stream(slices).limit(currentRecipe.mInputs.length).mapToInt(s -> s.progress).toArray()); + Arrays.stream(slices).limit(currentInputLength).mapToInt(s -> s.progress).toArray()); aNBT.setBoolean("stuck", stuck); aNBT.setLong("inputV", inputVoltage); aNBT.setLong("inputEU", inputEUt); @@ -347,7 +365,8 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas break; } } - setCurrentRecipe(loadedStack, recipe); + if (loadedStack == null || recipe == null) clearCurrentRecipe(); + else setCurrentRecipe(loadedStack, recipe); } @Override @@ -415,6 +434,19 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas } @Override + protected void drawTexts(DynamicPositionedColumn screenElements, SlotWidget inventorySlot) { + super.drawTexts(screenElements, inventorySlot); + SliceStatusWidget[] arr = Arrays.stream(slices).map(SliceStatusWidget::new).toArray(SliceStatusWidget[]::new); + screenElements.widgets(arr); + screenElements.widget(new FakeSyncWidget.IntegerSyncer(() -> currentInputLength, l -> { + currentInputLength = l; + for (SliceStatusWidget w : arr) { + w.updateText(); + } + })); + } + + @Override public boolean onRunningTick(ItemStack aStack) { if (currentRecipe == null) { criticalStopMachine(); @@ -424,7 +456,7 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas hatch_dataAccess.setActive(true); } - if (mInputBusses.size() < currentRecipe.mInputs.length) { + if (mInputBusses.size() < currentInputLength) { criticalStopMachine(); return false; } @@ -445,7 +477,7 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas if (slice.progress >= 0) { if (!foundWorking) { foundWorking = true; - mProgresstime = (slice.id + 1) * (mMaxProgresstime / currentRecipe.mInputs.length) - slice.progress; + mProgresstime = (slice.id + 1) * (mMaxProgresstime / currentInputLength) - slice.progress; } } if (slice.progress > 0) working++; @@ -466,7 +498,7 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas } if (getBaseMetaTileEntity().isAllowedToWork()) { - if (hasAllFluids(currentRecipe) && slices[0].start()) { + if (hasAllItems(currentRecipe) && hasAllFluids(currentRecipe) && slices[0].start()) { drainAllFluids(currentRecipe); mProgresstime = 0; } @@ -496,33 +528,38 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas // If we run into missing buses/hatches or bad inputs, we go to the next data stick. // This check only happens if we have a valid up-to-date data stick. - // Check Inputs align + // Check item Inputs align + if (!hasAllItems(tRecipe)) return null; + + // Check Fluid Inputs align + if (!hasAllFluids(tRecipe)) return null; + + if (GT_Values.D1) { + GT_FML_LOGGER.info("Check overclock"); + } + if (GT_Values.D1) { + GT_FML_LOGGER.info("Find available recipe"); + } + return tRecipe; + } + + private boolean hasAllItems(GT_Recipe.GT_Recipe_AssemblyLine tRecipe) { int aItemCount = tRecipe.mInputs.length; - if (mInputBusses.size() < aItemCount) return null; + if (mInputBusses.size() < aItemCount) return false; for (int i = 0; i < aItemCount; i++) { GT_MetaTileEntity_Hatch_InputBus tInputBus = mInputBusses.get(i); if (tInputBus == null) { - return null; + return false; } ItemStack tSlotStack = tInputBus.getStackInSlot(0); int tRequiredStackSize = isStackValidIngredient(tSlotStack, tRecipe.mInputs[i], tRecipe.mOreDictAlt[i]); - if (tRequiredStackSize < 0) return null; + if (tRequiredStackSize < 0) return false; if (GT_Values.D1) { GT_FML_LOGGER.info("Item: " + i + " accepted"); } } - - // Check Fluid Inputs align - if (!hasAllFluids(tRecipe)) return null; - - if (GT_Values.D1) { - GT_FML_LOGGER.info("Check overclock"); - } - if (GT_Values.D1) { - GT_FML_LOGGER.info("Find available recipe"); - } - return tRecipe; + return true; } private boolean hasAllFluids(GT_Recipe.GT_Recipe_AssemblyLine tRecipe) { @@ -577,14 +614,15 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas // and the first slice cannot find a input/fluid cannot be found // so we are safe to assume the old recipe no longer works @Override - public boolean checkRecipe(ItemStack aStack) { + @NotNull + public CheckRecipeResult checkProcessing() { if (GT_Values.D1) { GT_FML_LOGGER.info("Start Adv ALine recipe check"); } clearCurrentRecipe(); ArrayList<ItemStack> tDataStickList = getDataItems(2); if (tDataStickList.isEmpty()) { - return false; + return CheckRecipeResultRegistry.NO_DATA_STICKS; } if (GT_Values.D1) { GT_FML_LOGGER.info("Stick accepted, " + tDataStickList.size() + " Data Sticks found"); @@ -627,7 +665,7 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas if (GT_Values.D1) { GT_FML_LOGGER.info("Did not find a recipe"); } - return false; + return CheckRecipeResultRegistry.NO_RECIPE; } if (GT_Values.D1) { @@ -637,7 +675,7 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas if (!slices[0].start()) { clearCurrentRecipe(); // something very very wrong... - return false; + return CheckRecipeResultRegistry.NONE; } drainAllFluids(recipe); @@ -654,12 +692,17 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas if (GT_Values.D1) { GT_FML_LOGGER.info("Recipe successful"); } + return CheckRecipeResultRegistry.SUCCESSFUL; + } + + @Override + public boolean supportsVoidProtection() { return true; } @Override - public GT_Recipe.GT_Recipe_Map getRecipeMap() { - return null; + public Set<VoidingMode> getAllowedVoidingModes() { + return VoidingMode.ITEM_ONLY_MODES; } @Override @@ -726,13 +769,17 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas super.getWailaNBTData(player, tile, tag, world, x, y, z); if (currentRecipe == null || !getBaseMetaTileEntity().isActive()) return; NBTTagList l = new NBTTagList(); - for (int i = 0; i < currentRecipe.mInputs.length; i++) { + for (int i = 0; i < currentInputLength; i++) { l.appendTag(new NBTTagInt(slices[i].progress)); } tag.setTag(TAG_KEY_PROGRESS_TIMES, l); - tag.setInteger("mDuration", mMaxProgresstime / currentRecipe.mInputs.length); + tag.setInteger("mDuration", mMaxProgresstime / currentInputLength); } + /** + * Caller is responsible to check and ensure the hatches are there and has all the fluid needed. You will usually + * want to ensure hasAllFluid was called right before calling this, otherwise very bad things can happen. + */ private void drainAllFluids(GT_Recipe.GT_Recipe_AssemblyLine recipe) { for (int i = 0; i < recipe.mFluidInputs.length; i++) { mInputHatches.get(i).drain(ForgeDirection.UNKNOWN, recipe.mFluidInputs[i], true); @@ -760,6 +807,68 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas return -1; } + private class SliceStatusWidget extends TextWidget implements ISyncedWidget { + + private final Slice slice; + private int lastProgress = -2; + private Text text; + + private SliceStatusWidget(Slice slice) { + this.slice = slice; + updateText(); + } + + @Override + public boolean isEnabled() { + return super.isEnabled() && slice.progress <= 0 && currentInputLength > slice.id; + } + + @Override + public Text getText() { + return text; + } + + @Override + public void readOnClient(int id, PacketBuffer buf) { + if (id == 0) { + slice.progress = buf.readVarIntFromBuffer(); + updateText(); + checkNeedsRebuild(); + } + } + + public void updateText() { + String type = "unknown"; + if (slice.progress == 0) type = "stuck"; + else if (slice.progress < 0) type = "idle"; + text = Text.localised("ggfab.gui.advassline.slice." + type, slice.id); + } + + @Override + public void readOnServer(int id, PacketBuffer buf) {} + + @Override + public void detectAndSendChanges(boolean init) { + if (slice.progress != lastProgress) { + // suppress small normal progress update + if (slice.progress > 0 && lastProgress > 0 && lastProgress - slice.progress < 10) return; + lastProgress = slice.progress; + syncToClient(0, b -> b.writeVarIntToBuffer(slice.progress)); + } + } + + @Override + public void markForUpdate() {} + + @Override + public void unMarkForUpdate() {} + + @Override + public boolean isMarkedForUpdate() { + return false; + } + } + private class Slice { private final int id; @@ -777,9 +886,9 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas if (progress < 0) return; if (progress == 0 || --progress == 0) { // id==0 will be end of chain if 1 input, so we need a +1 here - if (id + 1 >= currentRecipe.mInputs.length) { - addOutput(currentRecipe.mOutput); - reset(); + if (id + 1 >= currentInputLength) { + if (addOutput(currentRecipe.mOutput) || !voidingMode.protectItem) reset(); + else stuck = true; } else { if (slices[id + 1].start()) reset(); else stuck = true; @@ -794,7 +903,7 @@ public class MTE_AdvAssLine extends GT_MetaTileEntity_ExtendedPowerMultiBlockBas ItemStack stack = bus.getStackInSlot(0); int size = isStackValidIngredient(stack, currentRecipe.mInputs[id], currentRecipe.mOreDictAlt[id]); if (size < 0) return false; - progress = mMaxProgresstime / currentRecipe.mInputs.length; + progress = mMaxProgresstime / currentInputLength; stack.stackSize -= size; bus.updateSlots(); return true; diff --git a/src/main/resources/assets/ggfab/lang/en_US.lang b/src/main/resources/assets/ggfab/lang/en_US.lang index df9dc6cba1..4de8e8a2f5 100644 --- a/src/main/resources/assets/ggfab/lang/en_US.lang +++ b/src/main/resources/assets/ggfab/lang/en_US.lang @@ -11,6 +11,9 @@ ggfab.waila.advassline.slice=Slice #%s: %s s / %s s ggfab.waila.advassline.slice.small=Slice #%s: %s ticks / %s ticks ggfab.waila.advassline.slice.idle=Slice #%s: Idle ggfab.waila.advassline.slice.stuck=Slice #%s: §4STUCK +ggfab.gui.advassline.slice.idle=Slice #%s: Idle +ggfab.gui.advassline.slice.stuck=Slice #%s: §4STUCK +ggfab.gui.advassline.slice.unknown=Slice #%s: ? ggfab.info.linked_input_bus.not_owned=§6The settings were copied from a different owner! ggfab.info.linked_input_bus.no_data=§6Configuration data not found! diff --git a/src/main/resources/assets/ggfab/lang/zh_CN.lang b/src/main/resources/assets/ggfab/lang/zh_CN.lang new file mode 100644 index 0000000000..c5a2da901d --- /dev/null +++ b/src/main/resources/assets/ggfab/lang/zh_CN.lang @@ -0,0 +1,28 @@ +ggfab.info.advassline.0=高级装配线教程 +ggfab.info.advassline.1=爱来自 §6GigaGram§rFab 与 w +ggfab.info.advassline.2=这种新式装配线支持流水线式装配,也就是说,这种装配线会逐一从输入总线中获取原材料,而不是像其他GT机器一样在启动时获取所有原材料。这种工作模式使得他获得了等同与当前配方物品输入数量的并行数。 +ggfab.info.advassline.3=你可以将高级装配线想象成一组装配刀片机,每个装配刀片可以互相独立的工作。 +ggfab.info.advassline.4=高级装配线会在输入总线第一格的内容与任意一个闪存记录的配方相符合时开始工作。第一装配刀片会从第一个输入总线获取输入。在(配方时间/物品输入个数)的时间后,第一装配刀片的工作结束了,之后便会将半成品转交给第二装配刀片,然后第二装配刀片再从自己的输入总线中获取输入。于此同时,在第二装配刀片工作时,第一装配刀片会继续尝试从第一输入总线中获取输入,如果这里仍然有足够的输入,则第一装配刀片会直接开始工作。 +ggfab.info.advassline.5=如果一个配方有n个输入,那么第N个装配刀片就是最终装配刀片,在他完成工作时就会将成品放到末尾的输出总线中。除最终装配刀片外,其他装配刀片在自己的工作结束时都会试图将半成品交给下一个刀片。如果下一个刀片无法从自己的输入总线中找到输入,则上一片刀片会停留在§4停滞§r状态,并最终使整个装配线阻塞。为了帮助你发现阻塞的装配线,任何含有§4停滞§r状态的装配刀片的装配线将会亮起橙红色指示灯。 +ggfab.info.advassline.6=高级装配线的瞬时能耗是正在工作的装配刀片的数量乘以当前配方的EU/t。§4停滞§r状态的装配刀片不会消耗能量。额外需要注意的是,本机器会使用所有能量供应舱室中最低的电压等级来计算配方等级与普通的非完美超频。 +ggfab.info.advassline.7=在使用一些特殊的能量供应舱室时,高级装配线可以进行额外的超频(称为§2激光超频§r),但是会使用比非完美超频更多的能量。每个§2激光超频§r会使得能量指数增加%s。 +ggfab.info.advassline.8=一层激光超频会使配方时间变为50%%,但会使用%s%%能量。二层激光超频会使配方时间变为25%%,但会使用%s%% (%s * %s)能量。激光超频仍然不会越过1tick极限。高级装配线在计算超频时会优先考虑并行,然后考虑非完美超频,最后进行§2激光超频§r。 +ggfab.waila.advassline.slice=装配刀片 #%s: %s秒 / %s秒 +ggfab.waila.advassline.slice.small=装配刀片 #%s: %s刻 / %s刻 +ggfab.waila.advassline.slice.idle=装配刀片 #%s: 空闲 +ggfab.waila.advassline.slice.stuck=装配刀片 #%s: §4停滞 +ggfab.gui.advassline.slice.idle=装配刀片 #%s: 空闲 +ggfab.gui.advassline.slice.stuck=装配刀片 #%s: §4停滞 +ggfab.gui.advassline.slice.unknown=装配刀片 #%s: ? + +ggfab.info.linked_input_bus.not_owned=§6记录的设置来自于不同的拥有者! +ggfab.info.linked_input_bus.invalid_data=§6找到了配置,但是它已不再有效! +ggfab.info.linked_input_bus.data_pasted=§2已粘贴频道("%s§2")和编程芯片配置! +ggfab.info.linked_input_bus.data_copied=§2已记录频道("%s§2")和编程芯片配置! +ggfab.info.linked_input_bus.no_channel=§6还没有设置频道! + +ggfab.info.biome=群系: + +ggfab.tooltip.linked_input_bus.change_freq_warn=如果这是最后一个本频道的输入总线,改变频道会使剩余的内容物洒在地上! +ggfab.tooltip.linked_input_bus.private=私有频道不会与其余玩家共享 +ggfab.tooltip.linked_input_bus.private.1=如果这是最后一个本频道的输入总线,改变频道会使剩余的内容物洒在地上!
\ No newline at end of file |