Merge branch 'master' into ae-navite-fluid-support

This commit is contained in:
Martin Robertz authored and GitHub committed 2025-09-30 19:19:14 +02:00
commit 766c2ff9ce
80 files changed
+3472 -1933

No files matched your search

+12 -12
View File
@@ -34,30 +34,30 @@
* For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph
*/
dependencies {
api('com.github.GTNewHorizons:NotEnoughItems:2.7.49-GTNH:dev')
api('com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-626-GTNH:dev')
api('com.github.GTNewHorizons:NotEnoughItems:2.7.91-GTNH:dev')
api('com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-690-GTNH:dev')
api('curse.maven:cofh-core-69162:2388751')
api('com.github.GTNewHorizons:waila:1.8.7:dev')
api("com.github.GTNewHorizons:GTNHLib:0.6.25:dev")
api('com.github.GTNewHorizons:waila:1.8.14:dev')
api("com.github.GTNewHorizons:GTNHLib:0.6.40:dev")
implementation("com.github.GTNewHorizons:WirelessCraftingTerminal:1.12.3:dev") {
implementation("com.github.GTNewHorizons:WirelessCraftingTerminal:1.12.7:dev") {
exclude group: 'com.github.GTNewHorizons', module: 'Applied-Energistics-2-Unofficial'
}
compileOnly('com.github.GTNewHorizons:Baubles-Expanded:2.1.8-GTNH:dev')
compileOnly('com.github.GTNewHorizons:Baubles-Expanded:2.1.15-GTNH:dev')
compileOnly('com.github.GTNewHorizons:ExtraCells2:2.5.35:dev') { transitive = false }
compileOnly('com.github.GTNewHorizons:ForestryMC:4.10.10:dev')
compileOnly('com.github.GTNewHorizons:EnderIO:2.9.16:dev')
compileOnly('com.github.GTNewHorizons:GT5-Unofficial:5.09.51.328:dev') {
compileOnly('com.github.GTNewHorizons:ForestryMC:4.10.17:dev')
compileOnly('com.github.GTNewHorizons:EnderIO:2.9.26:dev')
compileOnly('com.github.GTNewHorizons:GT5-Unofficial:5.09.51.469:dev') {
exclude group: 'com.github.GTNewHorizons', module: 'AE2FluidCraft-Rework'
exclude group: 'com.github.GTNewHorizons', module: 'Applied-Energistics-2-Unofficial'
}
compileOnly('thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev')
compileOnly('com.gregoriust.gregtech:gregtech_1.7.10:6.14.23:dev') { transitive = false }
compileOnly('com.github.GTNewHorizons:OpenComputers:1.11.15-GTNH:dev') { transitive = false }
compileOnly('com.github.GTNewHorizons:ThaumicEnergistics:1.7.7-GTNH:dev') { transitive = false }
compileOnly("com.github.GTNewHorizons:Hodgepodge:2.6.69:dev") { transitive = false }
compileOnly('com.github.GTNewHorizons:OpenComputers:1.11.19-GTNH:dev') { transitive = false }
compileOnly('com.github.GTNewHorizons:ThaumicEnergistics:1.7.14-GTNH:dev') { transitive = false }
compileOnly("com.github.GTNewHorizons:Hodgepodge:2.6.108:dev") { transitive = false }
runtimeOnlyNonPublishable("com.github.GTNewHorizons:DuraDisplay:1.3.4:dev")
}
+1 -1
View File
@@ -151,7 +151,7 @@ modrinthProjectId =
# type can be one of [project, version],
# and the name is the Modrinth project or version slug/id of the other mod.
# Example: required-project:fplib;optional-project:gasstation;incompatible-project:gregtech
# Note: GTNH Mixins is automatically set as a required dependency if usesMixins = true
# Note: UniMixins is automatically set as a required dependency if usesMixins = true.
modrinthRelations =
# Publishing to CurseForge requires you to set the CURSEFORGE_TOKEN environment variable to one of your CurseForge API tokens.
+1 -1
View File
@@ -17,7 +17,7 @@ pluginManagement {
}
plugins {
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.38'
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.42'
}
@@ -16,11 +16,13 @@ public interface ILevelViewable extends IGridHost, ISide, ISegmentedInventory, I
TileEntity getTile();
@Deprecated
default long getSortValue() {
TileEntity te = getTile();
return ((long) te.zCoord << 24) ^ ((long) te.xCoord << 8) ^ te.yCoord;
}
@Deprecated
default boolean shouldDisplay() {
return true;
}
@@ -39,6 +41,7 @@ public interface ILevelViewable extends IGridHost, ISide, ISegmentedInventory, I
return 1;
};
@Deprecated
default ItemStack getSelfItemStack() {
return null;
}
@@ -46,8 +49,11 @@ public interface ILevelViewable extends IGridHost, ISide, ISegmentedInventory, I
/**
* "Target" Display representation
*/
@Deprecated
default ItemStack getDisplayItemStack() {
return null;
}
LevelItemInfo[] getLevelItemInfoList();
}
@@ -0,0 +1,20 @@
package com.glodblock.github.api.registries;
import net.minecraft.item.ItemStack;
import org.jetbrains.annotations.NotNull;
public class LevelItemInfo {
public ItemStack stack;
public long quantity;
public long batchSize;
public LevelState state;
public LevelItemInfo(@NotNull ItemStack stack, long quantity, long batchSize, LevelState state) {
this.stack = stack;
this.quantity = quantity;
this.batchSize = batchSize;
this.state = state;
}
}
@@ -0,0 +1,11 @@
package com.glodblock.github.api.registries;
public enum LevelState {
None,
Idle,
Craft,
Export,
Error,
NotFound,
CantCraft
}
@@ -92,7 +92,7 @@ public class GuiCraftingStatus extends appeng.client.gui.implementations.GuiCraf
new CPacketInventoryAction(
InventoryAction.AUTO_CRAFT,
Ae2ReflectClient.getInventorySlots(this).size(),
0,
hoveredAEStack.getStackSize(),
hoveredAEStack));
return;
}
@@ -17,6 +17,7 @@ import com.glodblock.github.util.ModAndClassUtil;
import com.glodblock.github.util.NameConst;
import appeng.api.config.AdvancedBlockingMode;
import appeng.api.config.FuzzyMode;
import appeng.api.config.InsertionMode;
import appeng.api.config.LockCraftingMode;
import appeng.api.config.Settings;
@@ -43,6 +44,7 @@ public class GuiDualInterface extends GuiUpgradeable {
private GuiTabButton switcher;
private GuiImgButton BlockMode;
private GuiImgButton SmartBlockMode;
private GuiImgButton fuzzyMode;
private GuiToggleButton interfaceMode;
private GuiImgButton insertionMode;
private GuiImgButton sidelessMode;
@@ -152,6 +154,16 @@ public class GuiDualInterface extends GuiUpgradeable {
LockCraftingMode.NONE);
this.lockCraftingMode.visible = this.bc.getInstalledUpgrades(Upgrades.LOCK_CRAFTING) > 0;
this.buttonList.add(lockCraftingMode);
offset += 18;
this.fuzzyMode = new GuiImgButton(
this.guiLeft - 18,
this.guiTop + offset,
Settings.FUZZY_MODE,
FuzzyMode.IGNORE_ALL);
this.fuzzyMode.visible = this.bc.getInstalledUpgrades(Upgrades.FUZZY) > 0;
this.buttonList.add(fuzzyMode);
}
@Override
@@ -187,6 +199,9 @@ public class GuiDualInterface extends GuiUpgradeable {
if (this.lockCraftingMode != null) {
this.lockCraftingMode.set(((ContainerInterface) this.cvb).getLockCraftingMode());
}
if (this.fuzzyMode != null) {
this.fuzzyMode.set(((ContainerInterface) this.cvb).getFuzzyMode());
}
this.fontRendererObj.drawString(
getGuiDisplayName(StatCollector.translateToLocal(NameConst.GUI_FLUID_INTERFACE)),
8,
@@ -198,7 +213,7 @@ public class GuiDualInterface extends GuiUpgradeable {
protected String getBackground() {
if (!ModAndClassUtil.isBigInterface) return "guis/interface.png";
return switch (((ContainerInterface) this.cvb).getPatternCapacityCardsInstalled()) {
case -1 -> "guis/interfacenone.png";
case -1 -> "guis/interfacenonenoconfig.png";
case 1 -> "guis/interface2.png";
case 2 -> "guis/interface3.png";
case 3 -> "guis/interface4.png";
@@ -240,6 +255,8 @@ public class GuiDualInterface extends GuiUpgradeable {
.sendToServer(new PacketConfigButton(this.advancedBlockingMode.getSetting(), backwards));
} else if (btn == this.lockCraftingMode) {
NetworkHandler.instance.sendToServer(new PacketConfigButton(this.lockCraftingMode.getSetting(), backwards));
} else if (btn == this.fuzzyMode) {
NetworkHandler.instance.sendToServer(new PacketConfigButton(this.fuzzyMode.getSetting(), backwards));
}
}
@@ -256,5 +273,8 @@ public class GuiDualInterface extends GuiUpgradeable {
if (this.lockCraftingMode != null) {
this.lockCraftingMode.setVisibility(this.bc.getInstalledUpgrades(Upgrades.LOCK_CRAFTING) > 0);
}
if (this.fuzzyMode != null) {
this.fuzzyMode.setVisibility(this.bc.getInstalledUpgrades(Upgrades.FUZZY) > 0);
}
}
}
@@ -55,6 +55,7 @@ public class GuiFCPriority extends FCGuiAmount {
protected void addQty(final int i) {
try {
this.amountBox.setText(Long.toString(getAmount() + i));
this.amountBox.setCursorPositionEnd();
} catch (final NumberFormatException ignore) {}
try {
NetworkHandler.instance
@@ -45,9 +45,7 @@ public class GuiFluidCraftAmount extends FCGuiAmount {
this.guiTop + 53,
Settings.CRAFTING_MODE,
CraftingMode.STANDARD));
this.amountBox.setText("1");
this.amountBox.setSelectionPos(0);
((ContainerCraftAmount) this.inventorySlots).setAmountField(this.amountBox);
}
@Override
@@ -7,12 +7,10 @@ import net.minecraft.item.ItemStack;
import com.glodblock.github.client.gui.base.FCGuiMonitor;
import com.glodblock.github.client.gui.container.ContainerItemMonitor;
import com.glodblock.github.util.ModAndClassUtil;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.me.ItemRepo;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
public class GuiItemMonitor extends FCGuiMonitor<IAEItemStack> {
@@ -40,13 +38,6 @@ public class GuiItemMonitor extends FCGuiMonitor<IAEItemStack> {
super.drawFG(offsetX, offsetY, mouseX, mouseY);
}
@Override
public void drawScreen(final int mouseX, final int mouseY, final float btn) {
super.drawScreen(mouseX, mouseY, btn);
if (ModAndClassUtil.isSearchBar && AEConfig.instance.preserveSearchBar && searchField != null)
handleTooltip(mouseX, mouseY, searchField.new TooltipProvider());
}
@Override
public void setTextFieldValue(String displayName, int mousex, int mousey, ItemStack stack) {
setSearchString(displayName, true);
@@ -1,7 +1,5 @@
package com.glodblock.github.client.gui;
import static com.glodblock.github.client.gui.container.ContainerLevelMaintainer.createLevelValues;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
@@ -13,7 +11,6 @@ import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import net.minecraftforge.common.util.ForgeDirection;
@@ -23,12 +20,11 @@ import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.api.registries.LevelState;
import com.glodblock.github.client.gui.container.ContainerLevelMaintainer;
import com.glodblock.github.common.item.ItemWirelessUltraTerminal;
import com.glodblock.github.common.parts.PartLevelTerminal;
import com.glodblock.github.common.tile.TileLevelMaintainer;
import com.glodblock.github.common.tile.TileLevelMaintainer.State;
import com.glodblock.github.common.tile.TileLevelMaintainer.TLMTags;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.inventory.gui.MouseRegionManager;
import com.glodblock.github.inventory.item.IWirelessTerminal;
@@ -49,9 +45,6 @@ import appeng.client.gui.AEBaseGui;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.container.AEBaseContainer;
import appeng.container.slot.SlotFake;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.core.features.AEFeature;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketNEIDragClick;
import appeng.util.calculators.ArithHelper;
@@ -70,8 +63,6 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
private final Component[] component = new Component[TileLevelMaintainer.REQ_COUNT];
private final MouseRegionManager mouseRegions = new MouseRegionManager(this);
private Widget focusedWidget;
private int lastWorkingTick;
private int refreshTick;
private final CoFHFontRenderer render;
protected ItemStack icon = null;
@@ -89,7 +80,7 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
TEX_BG,
Minecraft.getMinecraft().getTextureManager(),
true);
this.refreshTick = 0;
if (ipl.player.openContainer instanceof AEBaseContainer container) {
var target = container.getTarget();
if (target instanceof PartLevelTerminal terminal) {
@@ -126,40 +117,11 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
}
}
}
public void postUpdate(List<IAEItemStack> list) {
for (Slot slot : this.cont.getRequestSlots()) {
if (!slot.getHasStack()) {
component[slot.getSlotIndex()].setState(State.None);
}
}
for (IAEItemStack is : list) {
NBTTagCompound data = is.getItemStack().getTagCompound();
if (data == null) {
if (AEConfig.instance.isFeatureEnabled(AEFeature.PacketLogging)) {
AELog.info("Received empty configuration: ", is);
}
continue;
}
long batch = data.getLong(TLMTags.Batch.tagName);
long quantity = data.getLong(TLMTags.Quantity.tagName);
int idx = data.getInteger(TLMTags.Index.tagName);
boolean isEnable = data.getBoolean(TLMTags.Enable.tagName);
State state = State.values()[data.getInteger(TLMTags.State.tagName)];
component[idx].getQty().textField.setText(String.valueOf(quantity));
component[idx].getBatch().textField.setText(String.valueOf(batch));
component[idx].getQty().validate();
component[idx].getBatch().validate();
component[idx].setEnable(isEnable);
component[idx].setState(state);
}
}
@Override
public void initGui() {
super.initGui();
this.lastWorkingTick = this.refreshTick;
for (int i = 0; i < TileLevelMaintainer.REQ_COUNT; i++) {
component[i] = new Component(
new Widget(
@@ -176,7 +138,8 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
new GuiFCImgButton(guiLeft + 9, guiTop + 20 + 19 * i, "ENABLE", "ENABLE", false),
new GuiFCImgButton(guiLeft + 9, guiTop + 20 + 19 * i, "DISABLE", "DISABLE", false),
new FCGuiLineField(fontRendererObj, guiLeft + 47, guiTop + 33 + 19 * i, 125),
this.buttonList);
this.buttonList,
this.cont);
}
if (this.icon != null) {
this.originalGuiBtn = new GuiTabButton(
@@ -188,11 +151,10 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
this.originalGuiBtn.setHideEdge(13);
this.buttonList.add(originalGuiBtn);
}
FluidCraft.proxy.netHandler.sendToServer(new CPacketLevelMaintainer(Action.Refresh));
}
@Override
public void drawScreen(final int mouseX, final int mouseY, final float btn) {
this.refreshTick++;
super.drawScreen(mouseX, mouseY, btn);
for (Component com : this.component) {
com.getQty().textField.handleTooltip(mouseX, mouseY, this);
@@ -205,12 +167,7 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY) {
mc.getTextureManager().bindTexture(TEX_BG);
drawTexturedModalRect(offsetX, offsetY, 0, 0, 176, ySize);
int tick = this.refreshTick;
int interval = 20;
if (tick > lastWorkingTick + interval && this.focusedWidget == null) {
FluidCraft.proxy.netHandler.sendToServer(new CPacketLevelMaintainer(Action.Refresh));
lastWorkingTick = this.refreshTick;
}
for (int i = 0; i < TileLevelMaintainer.REQ_COUNT; i++) {
this.component[i].draw();
}
@@ -294,20 +251,6 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
}
}
@Override
protected void handleMouseClick(final Slot slot, final int slotIdx, final int ctrlDown, final int mouseButton) {
if (slot instanceof SlotFluidConvertingFake && this.cont.getPlayerInv().getItemStack() != null) {
this.component[slot.getSlotIndex()].getQty().textField
.setText(String.valueOf(this.cont.getPlayerInv().getItemStack().stackSize));
return;
}
super.handleMouseClick(slot, slotIdx, ctrlDown, mouseButton);
}
public void updateAmount(int idx, int stackSize) {
this.component[idx].getQty().textField.setText(String.valueOf(stackSize));
}
@Override
protected void actionPerformed(final GuiButton btn) {
if (btn == originalGuiBtn) {
@@ -351,6 +294,15 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
return null;
}
@Override
protected void handleMouseClick(Slot slot, int slotIdx, int ctrlDown, int mouseButton) {
if (slot instanceof SlotFluidConvertingFake && this.cont.getPlayerInv().getItemStack() == null) {
slot.putStack(null);
this.component[slot.getSlotIndex()].reset();
}
super.handleMouseClick(slot, slotIdx, ctrlDown, mouseButton);
}
@Override
public boolean handleDragNDrop(GuiContainer gui, int mouseX, int mouseY, ItemStack draggedStack, int button) {
if (draggedStack == null) {
@@ -366,11 +318,9 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
for (int i = 0; i < this.cont.getRequestSlots().length; i++) {
SlotFluidConvertingFake slot = this.cont.getRequestSlots()[i];
if (slotAtPosition.equals(slot)) {
ItemStack itemStack = createLevelValues(draggedStack.copy());
itemStack.getTagCompound().setInteger(TLMTags.Index.tagName, i);
slot.putStack(itemStack);
NetworkHandler.instance.sendToServer(new PacketNEIDragClick(itemStack, slot.getSlotIndex()));
this.updateAmount(slot.getSlotIndex(), itemStack.stackSize);
slot.putStack(draggedStack);
component[i].reset();
NetworkHandler.instance.sendToServer(new PacketNEIDragClick(draggedStack, slot.getSlotIndex()));
return true;
}
}
@@ -382,26 +332,44 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
return false;
}
public void updateComponent(int index, long quantity, long batchSize, boolean isEnabled, LevelState state) {
if (index < 0 || index >= TileLevelMaintainer.REQ_COUNT) return;
component[index].setEnable(isEnabled);
component[index].setState(state);
component[index].getQty().textField.setText(String.valueOf(quantity));
component[index].getBatch().textField.setText(String.valueOf(batchSize));
component[index].getQty().validate();
component[index].getBatch().validate();
}
public void updateComponent(int index, LevelState state) {
if (index < 0 || index >= TileLevelMaintainer.REQ_COUNT) return;
component[index].setState(state);
}
private class Component {
public boolean isEnable = true;
public boolean isEnable = false;
private final Widget qty;
private final Widget batch;
private final GuiFCImgButton disable;
private final GuiFCImgButton enable;
private final GuiFCImgButton submit;
private final FCGuiLineField line;
private State state;
private LevelState state;
private final ContainerLevelMaintainer container;
public Component(Widget qtyInput, Widget batchInput, GuiFCImgButton submitBtn, GuiFCImgButton enableBtn,
GuiFCImgButton disableBtn, FCGuiLineField line, List<GuiButton> buttonList) {
GuiFCImgButton disableBtn, FCGuiLineField line, List<GuiButton> buttonList,
ContainerLevelMaintainer container) {
this.qty = qtyInput;
this.batch = batchInput;
this.enable = enableBtn;
this.disable = disableBtn;
this.submit = submitBtn;
this.line = line;
this.state = State.None;
this.state = LevelState.None;
this.container = container;
buttonList.add(this.submit);
buttonList.add(this.enable);
buttonList.add(this.disable);
@@ -435,18 +403,25 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
batch.validate();
if (qty.getAmount() != null) {
this.send(qty);
qty.textField.setText(String.valueOf(qty.getAmount()));
}
if (batch.getAmount() != null) {
this.send(batch);
batch.textField.setText(String.valueOf(batch.getAmount()));
}
didSomething = true;
} else if (this.enable == btn) {
this.setEnable(false);
FluidCraft.proxy.netHandler.sendToServer(new CPacketLevelMaintainer(Action.Enable, this.getIndex()));
didSomething = true;
} else if (this.disable == btn) {
FluidCraft.proxy.netHandler.sendToServer(new CPacketLevelMaintainer(Action.Disable, this.getIndex()));
didSomething = true;
if (this.container.getInventory().get(this.getIndex()) != null) {
this.setEnable(true);
FluidCraft.proxy.netHandler
.sendToServer(new CPacketLevelMaintainer(Action.Disable, this.getIndex()));
didSomething = true;
}
}
return didSomething;
}
@@ -499,6 +474,18 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_CURRENT) + " "
+ NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_ERROR));
}
case NotFound -> {
this.line.setColor(FCGuiColors.StateError.getColor());
message.add(
NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_CURRENT) + " "
+ NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_NOT_FOUND));
}
case CantCraft -> {
this.line.setColor(FCGuiColors.StateError.getColor());
message.add(
NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_CURRENT) + " "
+ NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_CANT_CRAFT));
}
default -> {
this.line.setColor(FCGuiColors.StateNone.getColor());
message.add(
@@ -515,7 +502,11 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_EXPORT));
message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_EXPORT_DESC) + "\n");
message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_ERROR));
message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_ERROR_DESC));
message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_ERROR_DESC) + "\n");
message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_NOT_FOUND));
message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_NOT_FOUND_DESC) + "\n");
message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_CANT_CRAFT));
message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_CANT_CRAFT_DESC));
} else {
message.add(NameConst.i18n(NameConst.TT_SHIFT_FOR_MORE));
}
@@ -531,9 +522,18 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
}
}
public void setState(State state) {
public void setState(LevelState state) {
this.state = state;
}
public void reset() {
this.qty.textField.setText("0");
this.batch.textField.setText("0");
this.qty.validate();
this.batch.validate();
this.setEnable(false);
this.setState(LevelState.None);
}
}
private class Widget {
@@ -585,7 +585,7 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
public void validate() {
final double result = Calculator.conversion(this.textField.getText());
if (Double.isNaN(result)) {
if (Double.isNaN(result) || result < 0) {
this.amount = null;
this.textField.setTextColor(0xFF0000);
} else {
@@ -1,13 +1,6 @@
package com.glodblock.github.client.gui;
import static com.glodblock.github.common.item.ItemWirelessUltraTerminal.hasInfinityBoosterCard;
import static com.glodblock.github.network.SPacketLevelTerminalUpdate.CLEAR_ALL_BIT;
import static com.glodblock.github.network.SPacketLevelTerminalUpdate.DISCONNECT_BIT;
import static com.glodblock.github.network.SPacketLevelTerminalUpdate.PacketAdd;
import static com.glodblock.github.network.SPacketLevelTerminalUpdate.PacketEntry;
import static com.glodblock.github.network.SPacketLevelTerminalUpdate.PacketOverwrite;
import static com.glodblock.github.network.SPacketLevelTerminalUpdate.PacketRemove;
import static com.glodblock.github.network.SPacketLevelTerminalUpdate.PacketRename;
import java.text.NumberFormat;
import java.util.ArrayList;
@@ -17,7 +10,6 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
@@ -34,8 +26,6 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import net.minecraftforge.common.util.ForgeDirection;
@@ -45,16 +35,17 @@ import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.api.registries.LevelItemInfo;
import com.glodblock.github.api.registries.LevelState;
import com.glodblock.github.client.gui.base.FCBaseMEGui;
import com.glodblock.github.client.gui.container.ContainerLevelTerminal;
import com.glodblock.github.common.tile.TileLevelMaintainer.State;
import com.glodblock.github.common.tile.TileLevelMaintainer.TLMTags;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.network.CPacketInventoryAction;
import com.glodblock.github.network.CPacketLevelTerminalCommands;
import com.glodblock.github.network.CPacketLevelTerminalCommands.Action;
import com.glodblock.github.network.CPacketRenamer;
import com.glodblock.github.network.SPacketLevelTerminalUpdate;
import com.glodblock.github.util.FCGuiColors;
import com.glodblock.github.util.ModAndClassUtil;
import com.glodblock.github.util.NameConst;
@@ -65,7 +56,6 @@ import appeng.api.config.TerminalFontSize;
import appeng.api.config.TerminalStyle;
import appeng.api.config.YesNo;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.gui.IGuiTooltipHandler;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiScrollbar;
@@ -83,7 +73,6 @@ import appeng.core.localization.PlayerMessages;
import appeng.helpers.InventoryAction;
import appeng.integration.IntegrationRegistry;
import appeng.integration.IntegrationType;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.Platform;
import appeng.util.ReadableNumberConverter;
import appeng.util.item.AEItemStack;
@@ -151,6 +140,7 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
};
searchFieldNames.setFocused(true);
extraOptionsText.add(ButtonToolTips.HighlightInterface.getLocal());
online = true;
}
public GuiLevelTerminal(final InventoryPlayer inventoryPlayer, final ITerminalHost te) {
@@ -184,8 +174,6 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
final int unusedSpace = height - ySize;
guiTop = (int) Math.floor(unusedSpace / (unusedSpace < 0 ? 3.8f : 2.0f));
// modeSwitchView = new GuiFCImgButton(guiLeft + xSize - 40, guiTop + 1, "SWITCH", "OFF", false);
// modeSwitchEdit = new GuiFCImgButton(guiLeft + xSize - 40, guiTop + 1, "SWITCH", "ON", false);
offsetY = guiTop + 8;
terminalStyleBox = new GuiImgButton(
guiLeft - 18,
@@ -290,7 +278,6 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
buttonList.add(terminalStyleBox);
buttonList.add(searchStringSave);
buttonList.add(craftingStatusBtn);
// buttonList.add(Objects.equals(currentMode, "OFF") ? modeSwitchView : modeSwitchEdit);
addSwitchGuiBtns();
super.drawScreen(mouseX, mouseY, btn);
@@ -322,11 +309,6 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
@Override
protected void actionPerformed(final GuiButton btn) {
// if (btn == modeSwitchView) {
// currentMode = "ON";
// } else if (btn == modeSwitchEdit) {
// currentMode = "OFF";
// } else
if (ModAndClassUtil.isSaveText && btn == searchStringSave) {
final boolean backwards = Mouse.isButtonDown(1);
@@ -362,7 +344,8 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
/* Draws the top part. */
drawTexturedModalRect(offsetX, offsetY, 0, 0, xSize, HEADER_HEIGHT);
/* Draws the middle part. */
Tessellator.instance.startDrawingQuads();
final Tessellator tess = Tessellator.instance;
tess.startDrawingQuads();
addTexturedRectToTesselator(
offsetX,
offsetY + HEADER_HEIGHT,
@@ -373,7 +356,7 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
(HEADER_HEIGHT + LevelTerminalSection.TITLE_HEIGHT + 1.0f) / 256.0f,
xSize / 256.0f,
(HEADER_HEIGHT + 106.0f) / 256.0f);
Tessellator.instance.draw();
tess.draw();
/* Draw the bottom part */
drawTexturedModalRect(offsetX, offsetY + HEADER_HEIGHT + viewHeight, 0, 158, xSize, INV_HEIGHT);
if (online) {
@@ -501,7 +484,8 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
private int drawEntry(LevelTerminalEntry entry, int viewY, int titleBottom, int relMouseX, int relMouseY) {
final EntityPlayer player = Minecraft.getMinecraft().thePlayer;
mc.getTextureManager().bindTexture(TEX_BG);
Tessellator.instance.startDrawingQuads();
final Tessellator tess = Tessellator.instance;
tess.startDrawingQuads();
int relY = 0;
final int slotLeftMargin = (VIEW_WIDTH - entry.rowSize * 18);
float lastZLevel = renderItem.zLevel;
@@ -530,7 +514,7 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
(173 + 18) / 256f);
}
}
Tessellator.instance.draw();
tess.draw();
/* Draw button */
if (viewY + entry.highlightButton.height > 0 && viewY < viewHeight) {
entry.highlightButton.yPosition = viewY + 1;
@@ -566,26 +550,21 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
if (viewY + rowYBot <= titleBottom) {
continue;
}
AppEngInternalInventory inv = entry.getInventory();
for (int col = 0; col < entry.rowSize; ++col) {
final int colLeft = col * 18 + slotLeftMargin + 1;
final int colRight = colLeft + 18 + 1;
final int slotIdx = row * entry.rowSize + col;
ItemStack stack = inv.getStackInSlot(slotIdx);
LevelItemInfo info = entry.infoList[slotIdx];
boolean tooltip = relMouseX > colLeft - 1 && relMouseX < colRight - 1
&& relMouseY >= Math.max(viewY + rowYTop, LevelTerminalSection.TITLE_HEIGHT)
&& relMouseY < Math.min(viewY + rowYBot, viewHeight);
if (stack != null) {
NBTTagCompound data = stack.getTagCompound();
ItemStack itemStack = data.hasKey(TLMTags.Stack.tagName)
? ItemStack.loadItemStackFromNBT(data.getCompoundTag(TLMTags.Stack.tagName))
: stack.copy();
long quantity = data.getLong(TLMTags.Quantity.tagName);
long batch = data.getLong(TLMTags.Batch.tagName);
State state = State.values()[data.getInteger(TLMTags.State.tagName)];
if (info != null) {
ItemStack itemStack = info.stack;
long quantity = info.quantity;
long batch = info.batchSize;
LevelState state = info.state;
GL11.glPushMatrix();
GL11.glTranslatef(colLeft, viewY + rowYTop + 1, ITEM_STACK_Z);
@@ -600,7 +579,7 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
case Idle -> FCGuiColors.StateIdle.getColor();
case Craft -> FCGuiColors.StateCraft.getColor();
case Export -> FCGuiColors.StateExport.getColor();
case Error -> FCGuiColors.StateError.getColor();
case Error, NotFound, CantCraft -> FCGuiColors.StateError.getColor();
case None -> FCGuiColors.StateNone.getColor();
};
int offset = 0;
@@ -608,7 +587,7 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
drawRect(offset, offset, offset + size, offset + size, color);
GL11.glTranslatef(0.0f, 0.0f, ITEM_STACK_OVERLAY_Z - ITEM_STACK_Z);
this.drawReadableAmount(fontRendererObj, quantity, true, 16777215);
if (batch > 0) {
if (batch >= 0) {
this.drawReadableAmount(fontRendererObj, batch, false, 16777215);
}
RenderHelper.disableStandardItemLighting();
@@ -622,7 +601,7 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
drawRect(0, 0, 16, 16, GuiColors.ItemSlotOverlayUnpowered.getColor());
}
} else {
tooltipStack = stack;
tooltipStack = itemStack;
}
GL11.glPopMatrix();
} else if (entry.filteredRecipes[slotIdx]) {
@@ -846,58 +825,50 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
&& mouseY < guiTop + HEADER_HEIGHT + viewHeight;
}
public void postUpdate(List<PacketEntry> updates, int statusFlags) {
if ((statusFlags & CLEAR_ALL_BIT) == CLEAR_ALL_BIT) {
/* Should clear all client entries. */
masterList.list.clear();
}
/* Should indicate disconnected, so the terminal turns dark. */
online = (statusFlags & DISCONNECT_BIT) != DISCONNECT_BIT;
for (PacketEntry cmd : updates) {
parsePacketCmd(cmd);
public void receivePackets(List<SPacketLevelTerminalUpdate.PacketEntry> packets) {
for (SPacketLevelTerminalUpdate.PacketEntry packet : packets) {
parsePacket(packet);
}
masterList.markDirty();
}
private void parsePacketCmd(PacketEntry cmd) {
long id = cmd.entryId;
if (cmd instanceof PacketAdd addCmd) {
private void parsePacket(SPacketLevelTerminalUpdate.PacketEntry packet) {
if (packet instanceof SPacketLevelTerminalUpdate.PacketAdd packetAdd) {
LevelTerminalEntry entry = new LevelTerminalEntry(
id,
addCmd.name,
addCmd.rows,
addCmd.rowSize,
addCmd.online).setLocation(addCmd.x, addCmd.y, addCmd.z, addCmd.dim, addCmd.side)
.setIcons(addCmd.selfItemStack, addCmd.displayItemStack).setItems(addCmd.items);
masterList.addEntry(entry);
} else if (cmd instanceof PacketRemove) {
masterList.removeEntry(id);
} else if (cmd instanceof PacketOverwrite owCmd) {
LevelTerminalEntry entry = masterList.list.get(id);
packetAdd.entryId,
packetAdd.name,
packetAdd.rows,
packetAdd.rowSize,
true).setLocation(packetAdd.x, packetAdd.y, packetAdd.z, packetAdd.dim, packetAdd.side)
.setInfoList(packetAdd.infolist);
this.masterList.addEntry(entry);
} else if (packet instanceof SPacketLevelTerminalUpdate.PacketRemove packetRemove) {
this.masterList.removeEntry(packetRemove.entryId);
} else if (packet instanceof SPacketLevelTerminalUpdate.PacketRename packetRename) {
LevelTerminalEntry entry = masterList.list.get(packetRename.entryId);
if (entry == null) return;
if (entry == null) {
return;
}
if (owCmd.itemsValid) {
if (owCmd.allItemUpdate) {
entry.fullItemUpdate(owCmd.items, owCmd.validIndices.length);
} else {
entry.partialItemUpdate(owCmd.items, owCmd.validIndices);
}
if (StatCollector.canTranslate(packetRename.newName)) {
entry.customName = StatCollector.translateToLocal(packetRename.newName);
} else {
entry.customName = StatCollector.translateToFallback(packetRename.newName);
}
masterList.isDirty = true;
} else if (cmd instanceof PacketRename renameCmd) {
LevelTerminalEntry entry = masterList.list.get(id);
} else if (packet instanceof SPacketLevelTerminalUpdate.PacketDisconnect) {
online = false;
}
if (entry != null) {
if (StatCollector.canTranslate(renameCmd.newName)) {
entry.customName = StatCollector.translateToLocal(renameCmd.newName);
} else {
entry.customName = StatCollector.translateToFallback(renameCmd.newName);
}
}
else if (packet instanceof SPacketLevelTerminalUpdate.PacketOverwriteSlot packetOverwirteSlot) {
LevelTerminalEntry entry = masterList.list.get(packetOverwirteSlot.entryId);
if (entry == null) return;
entry.infoList[packetOverwirteSlot.index] = packetOverwirteSlot.info;
masterList.isDirty = true;
} else if (packet instanceof SPacketLevelTerminalUpdate.PacketOverwirteAllSlot packetOverwirteAllSlot) {
LevelTerminalEntry entry = masterList.list.get(packetOverwirteAllSlot.entryId);
if (entry == null) return;
entry.infoList = packetOverwirteAllSlot.infoList;
masterList.isDirty = true;
}
}
@@ -932,22 +903,23 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
@Override
public List<String> handleItemTooltip(ItemStack stack, int mouseX, int mouseY, List<String> currentToolTip) {
if (stack == null || !isShiftKeyDown()) return currentToolTip;
if (stack != null && isShiftKeyDown() && stack.hasTagCompound()) {
NBTTagCompound data = stack.getTagCompound();
for (LevelTerminalSection section : this.masterList.getVisibleSections()) {
for (LevelTerminalEntry entry : section.visibleEntries) {
for (LevelItemInfo info : entry.infoList) {
if (info != null && info.stack.equals(stack)) {
currentToolTip.add(
I18n.format(NameConst.TT_LEVEL_MAINTAINER_REQUEST_SIZE, "\n", false) + ": "
+ NumberFormat.getInstance().format(info.quantity));
if (data.hasKey(TLMTags.Quantity.tagName)) {
long quantity = data.getLong(TLMTags.Quantity.tagName);
long batch = data.getLong(TLMTags.Batch.tagName);
currentToolTip.add(
I18n.format(NameConst.TT_LEVEL_MAINTAINER_REQUEST_SIZE, "\n", false) + ": "
+ NumberFormat.getNumberInstance(Locale.US).format(quantity));
if (batch > 0) {
currentToolTip.add(
I18n.format(NameConst.TT_LEVEL_MAINTAINER_BATCH_SIZE, "\n", false) + ": "
+ NumberFormat.getNumberInstance(Locale.US).format(batch));
if (info.batchSize >= 0) {
currentToolTip.add(
I18n.format(NameConst.TT_LEVEL_MAINTAINER_BATCH_SIZE, "\n", false) + ": "
+ NumberFormat.getInstance().format(info.batchSize));
}
break;
}
}
}
}
@@ -1102,13 +1074,7 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
String name;
List<LevelTerminalEntry> entries = new ArrayList<>();
Set<LevelTerminalEntry> visibleEntries = new TreeSet<>(Comparator.comparing(e -> {
if (e.displayItemStack != null) {
return e.displayItemStack.getDisplayName() + e.id;
} else {
return String.valueOf(e.id);
}
}));
Set<LevelTerminalEntry> visibleEntries = new TreeSet<>(Comparator.comparing(e -> e.customName + e.id));
int height;
private boolean isDirty = true;
boolean visible = false;
@@ -1148,18 +1114,22 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
entry.dispY = -9999;
// Find search terms
if (!output.isEmpty()) {
AppEngInternalInventory inv = entry.inv;
boolean shouldAdd = false;
for (int i = 0; i < inv.getSizeInventory(); ++i) {
ItemStack stack = inv.getStackInSlot(i);
if (itemStackMatchesSearchTerm(stack, output)) {
for (int i = 0; i < entry.infoList.length; ++i) {
if (entry.infoList[i] == null) {
entry.filteredRecipes[i] = true;
continue;
}
if (itemStackMatchesSearchTerm(entry.infoList[i].stack, output)) {
shouldAdd = true;
entry.filteredRecipes[i] = false;
} else {
entry.filteredRecipes[i] = true;
}
}
if (!shouldAdd) {
continue;
}
@@ -1207,12 +1177,9 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
private class LevelTerminalEntry {
String customName;
AppEngInternalInventory inv;
GuiFCImgButton highlightButton;
GuiFCImgButton renameButton;
GuiFCImgButton configButton;
/** Nullable - icon that represents the interface's "target" */
ItemStack displayItemStack;
LevelTerminalSection section;
long id;
int x, y, z, dim, side;
@@ -1220,7 +1187,8 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
int guiHeight;
int dispY = -9999;
boolean[] filteredRecipes;
int numItems = 0;
LevelItemInfo[] infoList;
LevelTerminalEntry(long id, String name, int rows, int rowSize, boolean online) {
this.id = id;
@@ -1236,7 +1204,6 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
customName = StatCollector.translateToFallback(name);
}
}
inv = new AppEngInternalInventory(null, rows * rowSize, 1);
highlightButton = new GuiFCImgButton(1, 0, "HIGHLIGHT", "YES");
renameButton = new GuiFCImgButton(1, 0, "EDIT", "YES");
configButton = new GuiFCImgButton(1, 0, "CONFIG", "YES");
@@ -1254,53 +1221,11 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
return this;
}
LevelTerminalEntry setIcons(ItemStack selfItemStack, ItemStack displayItemStack) {
this.displayItemStack = displayItemStack;
LevelTerminalEntry setInfoList(LevelItemInfo[] infoList) {
this.infoList = infoList;
return this;
}
public void fullItemUpdate(NBTTagList items, int newSize) {
inv = new AppEngInternalInventory(null, newSize);
rows = newSize / rowSize;
numItems = 0;
for (int i = 0; i < inv.getSizeInventory(); ++i) {
setItemInSlot(ItemStack.loadItemStackFromNBT(items.getCompoundTagAt(i)), i);
}
guiHeight = 18 * rows + 4;
}
LevelTerminalEntry setItems(NBTTagList items) {
assert items.tagCount() == inv.getSizeInventory();
for (int i = 0; i < items.tagCount(); ++i) {
setItemInSlot(ItemStack.loadItemStackFromNBT(items.getCompoundTagAt(i)), i);
}
return this;
}
public void partialItemUpdate(NBTTagList items, int[] validIndices) {
for (int i = 0; i < validIndices.length; ++i) {
setItemInSlot(ItemStack.loadItemStackFromNBT(items.getCompoundTagAt(i)), validIndices[i]);
}
}
private void setItemInSlot(ItemStack stack, int idx) {
final int oldHasItem = inv.getStackInSlot(idx) != null ? 1 : 0;
final int newHasItem = stack != null ? 1 : 0;
inv.setInventorySlotContents(idx, stack);
// Update item count
numItems += newHasItem - oldHasItem;
assert numItems >= 0;
}
public AppEngInternalInventory getInventory() {
return inv;
}
public boolean mouseClicked(int mouseX, int mouseY, int mouseButton) {
if (!section.visible || mouseButton < 0 || mouseButton > 2) {
return false;
@@ -1337,8 +1262,8 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
BlockPosHighlighter.highlightBlocks(
mc.thePlayer,
Collections.singletonList(blockPos),
PlayerMessages.LevelEmitterHighlighted.getName(),
PlayerMessages.LevelEmitterInAnotherDim.getName());
PlayerMessages.LevelEmitterHighlighted.getUnlocalized(),
PlayerMessages.LevelEmitterInAnotherDim.getUnlocalized());
mc.thePlayer.closeScreen();
}
return true;
@@ -1368,20 +1293,10 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
default -> null;// drop item:
};
if (action != null) {
ItemStack itemStack = getInventory().getStackInSlot(slotIdx);
if (itemStack != null && itemStack.hasTagCompound()
&& itemStack.getTagCompound().hasKey(TLMTags.Stack.tagName)) {
long batch = itemStack.getTagCompound().getLong(TLMTags.Batch.tagName);
NBTTagCompound stackData = itemStack.getTagCompound().getCompoundTag(TLMTags.Stack.tagName);
ItemStack is = ItemStack.loadItemStackFromNBT(stackData);
IAEItemStack stack = AEItemStack.create(is);
if (stack == null) return true;
stack.setStackSize(batch);
((AEBaseContainer) inventorySlots).setTargetStack(stack);
FluidCraft.proxy.netHandler.sendToServer(new CPacketInventoryAction(action, slotIdx, 0, stack));
}
if (action != null && this.infoList[slotIdx] != null) {
AEItemStack aeStack = AEItemStack.create(this.infoList[slotIdx].stack);
((AEBaseContainer) inventorySlots).setTargetStack(aeStack);
FluidCraft.proxy.netHandler.sendToServer(new CPacketInventoryAction(action, slotIdx, 0, aeStack));
}
return true;
@@ -117,8 +117,9 @@ public class GuiPatternMulti extends GuiAmount {
}
@Override
protected long addOrderAmount(final int i) {
return i + getAmount();
protected void addAmount(int i) {
this.amountTextField.setText(Long.toString(i + getAmount()));
this.amountTextField.setCursorPositionEnd();
}
@Override
@@ -9,18 +9,18 @@ import com.glodblock.github.client.gui.container.ContainerPatternValueAmount;
import com.glodblock.github.common.item.ItemWirelessUltraTerminal;
import com.glodblock.github.common.parts.PartFluidPatternTerminal;
import com.glodblock.github.common.parts.PartFluidPatternTerminalEx;
import com.glodblock.github.common.tile.TileSuperStockReplenisher;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.inventory.item.IWirelessTerminal;
import com.glodblock.github.inventory.item.WirelessPatternTerminalInventory;
import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.network.CPacketPatternValueSet;
import appeng.api.storage.ITerminalHost;
import appeng.core.localization.GuiText;
public class GuiPatternValueAmount extends FCGuiAmount {
public GuiPatternValueAmount(final InventoryPlayer inventoryPlayer, final ITerminalHost te) {
public GuiPatternValueAmount(final InventoryPlayer inventoryPlayer, final Object te) {
super(new ContainerPatternValueAmount(inventoryPlayer, te));
}
@@ -77,6 +77,9 @@ public class GuiPatternValueAmount extends FCGuiAmount {
} else if (target instanceof WirelessPatternTerminalInventory) {
this.myIcon = ItemAndBlockHolder.WIRELESS_PATTERN_TERM.stack();
this.originalGui = GuiType.WIRELESS_FLUID_PATTERN_TERMINAL;
} else if (target instanceof TileSuperStockReplenisher) {
this.myIcon = ItemAndBlockHolder.SUPER_STOCK_RERPLENISHER.stack();
this.originalGui = GuiType.GUI_SUPER_STOCK_REPLENISHER;
}
}
@@ -0,0 +1,116 @@
package com.glodblock.github.client.gui;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.client.gui.container.ContainerSuperStockReplenisher;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.common.tile.TileSuperStockReplenisher;
import com.glodblock.github.network.CPacketInventoryAction;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.client.gui.AEBaseGui;
import appeng.container.AEBaseContainer;
import appeng.container.slot.SlotFake;
import appeng.core.localization.GuiText;
import appeng.helpers.InventoryAction;
import appeng.util.item.AEItemStack;
public class GuiSuperStockReplenisher extends AEBaseGui {
private static final ResourceLocation TEX_BG = FluidCraft.resource("textures/gui/superStockReplenisher.png");
private Map<Integer, IAEStack<?>> list = new HashMap<>();
public GuiSuperStockReplenisher(InventoryPlayer ipl, TileSuperStockReplenisher tile) {
super(new ContainerSuperStockReplenisher(ipl, tile));
this.ySize = 251;
this.xSize = 216;
}
@Override
protected void handleMouseClick(Slot slot, int slotIdx, int ctrlDown, int mouseButton) {
if (mouseButton == 3) {
if (slot instanceof SlotFake) {
if (slot.getHasStack()) {
InventoryAction action = InventoryAction.SET_PATTERN_VALUE;
IAEItemStack stack = AEItemStack.create(slot.getStack());
((AEBaseContainer) this.inventorySlots).setTargetStack(stack);
for (int i = 0; i < this.inventorySlots.inventorySlots.size(); i++) {
if (slot.equals(this.inventorySlots.inventorySlots.get(i))) {
FluidCraft.proxy.netHandler.sendToServer(new CPacketInventoryAction(action, i, 0, stack));
}
}
return;
}
}
}
super.handleMouseClick(slot, slotIdx, ctrlDown, mouseButton);
}
@Override
public void func_146977_a(Slot s) {
if (s instanceof SlotFake) {
this.drawFillStatus(s);
}
super.func_146977_a(s);
}
private void drawFillStatus(Slot slotIn) {
int offsetX = slotIn.xDisplayPosition - 8;
int offsetY = slotIn.yDisplayPosition - 11;
ItemStack itemstack = slotIn.getStack();
int slotInt = slotIn.slotNumber;
if (itemstack != null) {
String s = "0%";
if (slotInt > 0 && slotInt < 10) {
IAEStack<?> aeStack = list.get(slotInt - 1);
if (aeStack != null)
s = (int) (((float) aeStack.getStackSize() / ItemFluidPacket.getFluidAmount(itemstack)) * 100)
+ "%";
} else if (slotInt > 9 && slotInt < 73) {
IAEStack<?> aeStack = list.get(slotInt + 90);
if (aeStack != null && itemstack.stackSize > 0) {
long i = aeStack.getStackSize();
s = (int) (((float) i / itemstack.stackSize) * 100) + "%";
}
}
float scale = 0.5f;
float shiftX = 2;
float shiftY = 1;
final float inverseScaleFactor = 1.0f / scale;
final int X = (int) (((float) offsetX - shiftX + 10.0f) * inverseScaleFactor);
final int Y = (int) (((float) offsetY - shiftY + 16.0f - 7.0f * scale) * inverseScaleFactor);
GL11.glTranslatef(0.0f, 0.0f, 200.0f);
GL11.glScaled(scale, scale, scale);
this.fontRendererObj.drawStringWithShadow(s, X, Y, 16777215);
GL11.glScaled(inverseScaleFactor, inverseScaleFactor, inverseScaleFactor);
GL11.glTranslatef(0.0f, 0.0f, -200.0f);
}
}
@Override
public void drawFG(int offsetX, int offsetY, int mouseX, int mouseY) {
fontRendererObj.drawString(GuiText.inventory.getLocal(), 8, ySize - 94, 0x404040);
}
@Override
public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY) {
this.bindTexture(TEX_BG);
this.drawTexturedModalRect(offsetX, offsetY, 0, 0, xSize, ySize);
}
public void update(Map<Integer, IAEStack<?>> map) {
this.list = map;
}
}
@@ -1,7 +1,6 @@
package com.glodblock.github.client.gui.base;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
@@ -12,6 +11,7 @@ import com.glodblock.github.inventory.gui.GuiType;
import appeng.client.gui.AEBaseGui;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.client.gui.widgets.MEGuiTextField;
import appeng.container.AEBaseContainer;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
@@ -20,7 +20,7 @@ import appeng.util.calculators.Calculator;
public abstract class FCGuiAmount extends AEBaseGui {
protected GuiTextField amountBox;
protected MEGuiTextField amountBox;
protected GuiTabButton originalGuiBtn;
protected GuiButton submit;
protected GuiButton plus1;
@@ -72,16 +72,10 @@ public abstract class FCGuiAmount extends AEBaseGui {
this.originalGuiBtn.setHideEdge(13);
}
this.amountBox = new GuiTextField(
this.fontRendererObj,
this.guiLeft + 62,
this.guiTop + 57,
59,
this.fontRendererObj.FONT_HEIGHT);
this.amountBox.setEnableBackgroundDrawing(false);
this.amountBox = new MEGuiTextField(61, 12);
this.amountBox.x = this.guiLeft + 60;
this.amountBox.y = this.guiTop + 55;
this.amountBox.setMaxStringLength(16);
this.amountBox.setTextColor(0xFFFFFF);
this.amountBox.setVisible(true);
this.amountBox.setFocused(true);
}
@@ -134,6 +128,7 @@ public abstract class FCGuiAmount extends AEBaseGui {
}
String out = Long.toString(resultI);
this.amountBox.setText(out);
this.amountBox.setCursorPositionEnd();
} catch (final NumberFormatException ignore) {}
}
@@ -16,7 +16,7 @@ import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.client.gui.FCGuiTextField;
import com.glodblock.github.client.gui.GuiFluidMonitor;
import com.glodblock.github.client.gui.GuiItemMonitor;
import com.glodblock.github.client.gui.container.base.FCContainerMonitor;
import com.glodblock.github.inventory.InventoryHandler;
@@ -26,12 +26,15 @@ import com.glodblock.github.util.Ae2ReflectClient;
import com.glodblock.github.util.ModAndClassUtil;
import appeng.api.config.CraftingStatus;
import appeng.api.config.PinsState;
import appeng.api.config.SearchBoxFocusPriority;
import appeng.api.config.SearchBoxMode;
import appeng.api.config.Settings;
import appeng.api.config.TerminalStyle;
import appeng.api.config.YesNo;
import appeng.api.implementations.tiles.IViewCellStorage;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.ITerminalPins;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IDisplayRepo;
@@ -42,7 +45,10 @@ import appeng.client.gui.widgets.GuiScrollbar;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.client.gui.widgets.IDropToFillTextField;
import appeng.client.gui.widgets.ISortSource;
import appeng.client.gui.widgets.MEGuiTextField;
import appeng.client.me.InternalSlotME;
import appeng.client.me.ItemRepo;
import appeng.client.me.PinSlotME;
import appeng.client.me.SlotDisconnected;
import appeng.client.me.SlotME;
import appeng.container.AEBaseContainer;
@@ -60,7 +66,9 @@ import appeng.core.localization.ButtonToolTips;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.core.sync.packets.PacketPinsUpdate;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.helpers.IPinsHandler;
import appeng.helpers.InventoryAction;
import appeng.integration.IntegrationRegistry;
import appeng.integration.IntegrationType;
@@ -72,7 +80,7 @@ import codechicken.nei.util.TextHistory;
// TODO why is this copy pasting all the UI code from AE2 instead of reusing it ???
public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
implements ISortSource, IConfigManagerHost, IDropToFillTextField {
implements ISortSource, IConfigManagerHost, IDropToFillTextField, IPinsHandler {
public static int craftingGridOffsetX;
public static int craftingGridOffsetY;
@@ -86,7 +94,7 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
public GuiTabButton craftingStatusBtn;
protected IDisplayRepo repo;
protected GuiImgButton craftingStatusImgBtn;
protected FCGuiTextField searchField;
protected MEGuiTextField searchField;
protected int perRow = 9;
protected int reservedSpace = 0;
protected boolean customSortOrder = true;
@@ -102,7 +110,14 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
protected GuiImgButton terminalStyleBox;
protected GuiImgButton searchStringSave;
protected GuiImgButton typeFilter;
protected GuiImgButton pinsStateButton;
protected boolean hasShiftKeyDown = false;
private PinsState pinsState;
public final boolean hasPinHost;
private boolean canBeAutoFocused;
private boolean isAutoFocused;
protected int currentMouseY;
protected int currentMouseX;
@SuppressWarnings("unchecked")
public FCGuiMonitor(final InventoryPlayer inventoryPlayer, final ITerminalHost te, final FCContainerMonitor<T> c) {
@@ -115,6 +130,8 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
this.configSrc = ((IConfigurableObject) this.inventorySlots).getConfigManager();
(this.monitorableContainer = (FCContainerMonitor<T>) this.inventorySlots).setGui(this);
this.viewCell = te instanceof IViewCellStorage;
pinsState = (PinsState) configSrc.getSetting(Settings.PINS_STATE);
hasPinHost = te instanceof ITerminalPins && !(this instanceof GuiFluidMonitor);
}
public int getOffsetY() {
@@ -131,12 +148,13 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
this.getScrollBar().setTop(18).setLeft(175).setHeight(this.rows * 18 - 2);
this.getScrollBar().setRange(
0,
(this.repo.size() + this.perRow - 1) / this.perRow - this.rows,
(this.repo.size() + pinsState.ordinal() * 9 + this.perRow - 1) / this.perRow - this.rows,
Math.max(1, this.rows / 6));
}
@Override
protected void actionPerformed(final GuiButton btn) {
memoryText = this.searchField.getText();
if (btn == this.craftingStatusBtn || btn == this.craftingStatusImgBtn) {
InventoryHandler.switchGui(GuiType.CRAFTING_STATUS);
}
@@ -151,6 +169,15 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
AEConfig.instance.settings.putSetting(iBtn.getSetting(), next);
} else if (ModAndClassUtil.isSaveText && btn == this.searchStringSave) {
AEConfig.instance.preserveSearchBar = next == YesNo.YES;
} else if (btn == this.pinsStateButton) {
try {
if (next.ordinal() >= rows) return; // ignore to avoid hiding terminal inventory
final PacketPinsUpdate p = new PacketPinsUpdate((PinsState) next);
NetworkHandler.instance.sendToServer(p);
} catch (final IOException e) {
AELog.debug(e);
}
} else {
try {
NetworkHandler.instance
@@ -161,7 +188,6 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
}
iBtn.set(next);
if (next.getClass() == SearchBoxMode.class || next.getClass() == TerminalStyle.class) {
memoryText = this.searchField.getText();
super.scheduleGuiResize();
}
}
@@ -169,6 +195,19 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
super.actionPerformed(btn);
}
private void adjustPinsSize() {
final int pinMaxSize = rows - 1;
if (pinsState.ordinal() <= pinMaxSize) return;
try {
PinsState newState = PinsState.fromOrdinal(pinMaxSize);
final PacketPinsUpdate p = new PacketPinsUpdate(newState);
NetworkHandler.instance.sendToServer(p);
} catch (final IOException e) {
AELog.debug(e);
}
}
@Override
public void initGui() {
Keyboard.enableRepeatEvents(true);
@@ -199,10 +238,26 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
}
this.getMeSlots().clear();
for (int y = 0; y < this.rows; y++) {
// make sure we have space at least for one row of normal slots, because pins not adjusted by scroll bar
adjustPinsSize();
int pinsRows = pinsState.ordinal();
for (int y = 0; y < pinsRows; y++) {
for (int x = 0; x < this.perRow; x++) {
this.getMeSlots()
.add(new InternalSlotME(this.repo, x + y * this.perRow, this.offsetX + x * 18, 18 + y * 18));
.add(new PinSlotME(this.repo, x + y * this.perRow, this.offsetX + x * 18, y * 18 + 18));
}
}
for (int y = 0; y < this.rows - pinsRows; y++) {
for (int x = 0; x < this.perRow; x++) {
this.getMeSlots().add(
new InternalSlotME(
this.repo,
x + y * this.perRow,
this.offsetX + x * 18,
18 + y * 18 + pinsRows * 18));
}
}
@@ -224,6 +279,7 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
this.offsetY = this.guiTop + 8;
buttonList.clear();
if (this.customSortOrder) {
this.buttonList.add(
this.SortByBox = new GuiImgButton(
@@ -286,18 +342,19 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
AEConfig.instance.settings.getSetting(Settings.TERMINAL_STYLE)));
this.offsetY += 20;
// Right now 80 > offsetX, but that can be changed later.
// noinspection DataFlowIssue
this.searchField = new FCGuiTextField(
this.fontRendererObj,
this.guiLeft + Math.max(80, this.offsetX),
this.guiTop + 4,
90,
12);
this.searchField.setEnableBackgroundDrawing(false);
this.searchField = new MEGuiTextField(90, 12) {
@Override
public void onTextChange(final String oldText) {
final String text = getText();
repo.setSearchString(text);
repo.updateView();
setScrollBar();
}
};
this.searchField.x = this.guiLeft + Math.max(80, this.offsetX);
this.searchField.y = this.guiTop + 4;
this.searchField.setMaxStringLength(25);
this.searchField.setTextColor(0xFFFFFF);
this.searchField.setVisible(true);
if (ModAndClassUtil.isSearchStringTooltip)
searchField.setMessage(ButtonToolTips.SearchStringTooltip.getLocal());
@@ -323,8 +380,19 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
}
}
if (hasPinHost) {
this.buttonList.add(
this.pinsStateButton = new GuiImgButton(
this.guiLeft + 177,
this.guiTop + 18 + (rows * 18) + 26,
Settings.PINS_STATE,
configSrc.getSetting(Settings.PINS_STATE)));
}
final Enum<?> setting = AEConfig.instance.settings.getSetting(Settings.SEARCH_MODE);
this.searchField.setFocused(SearchBoxMode.AUTOSEARCH == setting || SearchBoxMode.NEI_AUTOSEARCH == setting);
this.canBeAutoFocused = SearchBoxMode.AUTOSEARCH == setting || SearchBoxMode.NEI_AUTOSEARCH == setting;
this.searchField.setFocused(this.canBeAutoFocused);
this.isAutoFocused = this.canBeAutoFocused;
if (ModAndClassUtil.isSearchBar && (AEConfig.instance.preserveSearchBar || this.isSubGui())) {
setSearchString(memoryText, false);
@@ -360,6 +428,7 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
public void setSearchString(String memoryText, boolean updateView) {
this.searchField.setText(memoryText);
this.searchField.setCursorPositionEnd();
this.repo.setSearchString(memoryText);
if (updateView) {
this.repo.updateView();
@@ -369,13 +438,8 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
@Override
protected void mouseClicked(final int xCoord, final int yCoord, final int btn) {
final Enum<?> searchMode = AEConfig.instance.settings.getSetting(Settings.SEARCH_MODE);
if (searchMode != SearchBoxMode.AUTOSEARCH && searchMode != SearchBoxMode.NEI_AUTOSEARCH) {
this.searchField.mouseClicked(xCoord, yCoord, btn);
}
if (btn == 1 && this.searchField.isMouseIn(xCoord, yCoord)) {
setSearchString("", true);
}
this.searchField.mouseClicked(xCoord, yCoord, btn);
isAutoFocused = false;
super.mouseClicked(xCoord, yCoord, btn);
}
@@ -527,13 +591,22 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
return;
}
if (slot instanceof SlotME) {
if (slot instanceof SlotME sme) {
InventoryAction action = null;
IAEItemStack stack = null;
switch (mouseButton) {
case 0: // pickup / set-down.
action = ctrlDown == 1 ? InventoryAction.SPLIT_OR_PLACE_SINGLE : InventoryAction.PICKUP_OR_SET_DOWN;
stack = ((SlotME) slot).getAEStack();
if (sme.isPin() && player.inventory.getItemStack() != null) {
final PacketInventoryAction p = new PacketInventoryAction(
InventoryAction.SET_PIN,
sme.getPinIndex(),
0);
NetworkHandler.instance.sendToServer(p);
return;
}
stack = sme.getAEStack();
if (stack != null && action == InventoryAction.PICKUP_OR_SET_DOWN
&& stack.getStackSize() == 0
&& player.inventory.getItemStack() == null) {
@@ -541,6 +614,15 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
}
break;
case 1:
if (sme.isPin() && ctrlDown == 1) { // clear pin
final PacketInventoryAction p = new PacketInventoryAction(
InventoryAction.SET_PIN,
sme.getPinIndex(),
-1);
NetworkHandler.instance.sendToServer(p);
return;
}
action = ctrlDown == 1 ? InventoryAction.PICKUP_SINGLE : InventoryAction.SHIFT_CLICK;
stack = ((SlotME) slot).getAEStack();
break;
@@ -640,6 +722,9 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
if (this.searchField != null) {
this.searchField.drawTextBox();
}
this.currentMouseX = mouseX;
this.currentMouseY = mouseY;
}
protected String getBackground() {
@@ -662,18 +747,29 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
@Override
protected void keyTyped(final char character, final int key) {
if (!this.checkHotbarKeys(key)) {
if (character == ' ' && this.searchField.getText().isEmpty()) {
return;
}
if (character == ' ' && this.searchField.getText().isEmpty()) {
return;
}
if (this.searchField.textboxKeyTyped(character, key)) {
this.repo.setSearchString(this.searchField.getText());
this.repo.updateView();
this.setScrollBar();
} else {
super.keyTyped(character, key);
}
boolean skipHotbarCheck = searchField.isFocused()
&& (AEConfig.instance.searchBoxFocusPriority == SearchBoxFocusPriority.ALWAYS
|| (AEConfig.instance.searchBoxFocusPriority == SearchBoxFocusPriority.NO_AUTOSEARCH
&& !isAutoFocused));
if (!skipHotbarCheck && checkHotbarKeys(key)) {
return;
}
final boolean mouseInGui = this
.isPointInRegion(0, 0, this.xSize, this.ySize, this.currentMouseX, this.currentMouseY);
if (this.canBeAutoFocused && !searchField.isFocused() && mouseInGui) {
searchField.setFocused(true);
isAutoFocused = true;
}
if (!searchField.textboxKeyTyped(character, key)) {
super.keyTyped(character, key);
}
}
@@ -721,6 +817,13 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
this.typeFilter.set(this.configSrc.getSetting(Settings.TYPE_FILTER));
}
if (this.pinsStateButton != null) {
pinsState = (PinsState) this.configSrc.getSetting(Settings.PINS_STATE);
this.pinsStateButton.set(pinsState);
initGui();
}
this.repo.updateView();
}
@@ -748,13 +851,6 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
this.standardSize = standardSize;
}
@Override
public void drawScreen(final int mouseX, final int mouseY, final float btn) {
super.drawScreen(mouseX, mouseY, btn);
if (ModAndClassUtil.isSearchBar && AEConfig.instance.preserveSearchBar && searchField != null)
handleTooltip(mouseX, mouseY, searchField.new TooltipProvider());
}
public boolean isOverSearchField(int x, int y) {
return searchField.isMouseIn(x, y);
}
@@ -786,4 +882,33 @@ public abstract class FCGuiMonitor<T extends IAEStack<T>> extends FCBaseMEGui
public boolean isOverTextField(int mousex, int mousey) {
return searchField.isMouseIn(mousex, mousey);
}
@Override
public void setAEPins(IAEItemStack[] pins) {
if (repo instanceof ItemRepo) repo.setAEPins(pins);
}
@Override
public void setPinsState(PinsState state) {
configSrc.putSetting(Settings.PINS_STATE, state);
}
@SuppressWarnings("SameParameterValue")
protected boolean isPointInRegion(int rectX, int rectY, int rectWidth, int rectHeight, int pointX, int pointY) {
pointX -= this.guiLeft;
pointY -= this.guiTop;
return pointX >= rectX - 1 && pointX < rectX + rectWidth + 1
&& pointY >= rectY - 1
&& pointY < rectY + rectHeight + 1;
}
// Moving items via hotbar keys in terminals isn't working anyway.
// Let's disable hotbar keys processing for terminal slots to allow proper input of numbers in the search field
@Override
protected boolean checkHotbarKeys(int keyCode) {
if (theSlot instanceof SlotME) {
return false;
}
return super.checkHotbarKeys(keyCode);
}
}
@@ -1,20 +1,15 @@
package com.glodblock.github.client.gui.container;
import java.util.Objects;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.common.tile.TileLevelMaintainer;
import com.glodblock.github.common.tile.TileLevelMaintainer.State;
import com.glodblock.github.common.tile.TileLevelMaintainer.TLMTags;
import com.glodblock.github.inventory.AeItemStackHandler;
import com.glodblock.github.inventory.slot.SlotFluidConvertingFake;
import com.glodblock.github.util.Util;
import com.glodblock.github.network.SPacketLevelMaintainerGuiUpdate;
import appeng.api.config.SecurityPermissions;
import appeng.container.AEBaseContainer;
@@ -26,6 +21,10 @@ public class ContainerLevelMaintainer extends AEBaseContainer {
private final TileLevelMaintainer tile;
private final SlotFluidConvertingFake[] requestSlots = new SlotFluidConvertingFake[TileLevelMaintainer.REQ_COUNT];
private static final int UPDATE_INTERVAL = 20;
private boolean isFirstUpdate = true;
private int updateCount = UPDATE_INTERVAL;
public ContainerLevelMaintainer(InventoryPlayer ipl, TileLevelMaintainer tile) {
super(ipl, tile);
this.tile = tile;
@@ -48,49 +47,14 @@ public class ContainerLevelMaintainer extends AEBaseContainer {
@Override
public void doAction(EntityPlayerMP player, InventoryAction action, int slotId, long id) {
Slot slot = getSlot(slotId);
if (slot instanceof SlotFluidConvertingFake) {
if (getSlot(slotId) instanceof SlotFluidConvertingFake slot) {
final ItemStack stack = player.inventory.getItemStack();
switch (action) {
case PICKUP_OR_SET_DOWN -> {
case PICKUP_OR_SET_DOWN, PLACE_SINGLE, SPLIT_OR_PLACE_SINGLE -> {
if (stack == null) {
slot.putStack(null);
} else {
((SlotFluidConvertingFake) slot).putConvertedStack(createLevelValues(stack.copy()));
}
}
case PLACE_SINGLE -> {
if (stack != null) {
((SlotFluidConvertingFake) slot).putConvertedStack(
createLevelValues(Objects.requireNonNull(Util.copyStackWithSize(stack, 1))));
}
}
case SPLIT_OR_PLACE_SINGLE -> {
ItemStack inSlot = slot.getStack();
if (inSlot != null) {
if (stack == null) {
slot.putStack(
createLevelValues(
Objects.requireNonNull(
Util.copyStackWithSize(
inSlot,
Math.max(1, inSlot.stackSize - 1)))));
} else if (stack.isItemEqual(inSlot)) {
slot.putStack(
createLevelValues(
Objects.requireNonNull(
Util.copyStackWithSize(
inSlot,
Math.min(
inSlot.getMaxStackSize(),
inSlot.stackSize + 1)))));
} else {
((SlotFluidConvertingFake) slot).putConvertedStack(
createLevelValues(Objects.requireNonNull(Util.copyStackWithSize(stack, 1))));
}
} else if (stack != null) {
((SlotFluidConvertingFake) slot).putConvertedStack(
createLevelValues(Objects.requireNonNull(Util.copyStackWithSize(stack, 1))));
slot.putConvertedStack(stack);
}
}
default -> {}
@@ -109,10 +73,8 @@ public class ContainerLevelMaintainer extends AEBaseContainer {
for (int i = 0; i < this.getRequestSlots().length; i++) {
SlotFluidConvertingFake slot = this.getRequestSlots()[i];
if (!slot.getHasStack()) {
ItemStack itemStack = ((Slot) this.inventorySlots.get(idx)).getStack();
ItemStack configuration = createLevelValues(itemStack.copy());
configuration.getTagCompound().setInteger(TLMTags.Index.tagName, i);
slot.putConvertedStack(configuration);
ItemStack itemStack = this.inventorySlots.get(idx).getStack();
tile.updateStack(i, itemStack.copy());
break;
}
}
@@ -123,35 +85,23 @@ public class ContainerLevelMaintainer extends AEBaseContainer {
@Override
public void detectAndSendChanges() {
super.detectAndSendChanges();
if (Platform.isClient()) {
return;
}
this.verifyPermissions(SecurityPermissions.BUILD, false);
super.detectAndSendChanges();
if (this.updateCount++ >= UPDATE_INTERVAL) {
this.updateGui();
}
}
public static ItemStack createLevelValues(ItemStack itemStack) {
var data = itemStack.hasTagCompound() ? itemStack.getTagCompound() : new NBTTagCompound();
if (!data.hasKey(TLMTags.Stack.tagName)) {
var itemStackTag = new NBTTagCompound();
itemStack.copy().writeToNBT(itemStackTag);
data.setTag(TLMTags.Stack.tagName, itemStackTag);
}
if (!data.hasKey(TLMTags.Quantity.tagName)) {
data.setLong(TLMTags.Quantity.tagName, itemStack.stackSize > 0 ? itemStack.stackSize : 1);
}
if (!data.hasKey(TLMTags.Batch.tagName)) {
data.setLong(TLMTags.Batch.tagName, 1);
}
if (!data.hasKey(TLMTags.Enable.tagName)) {
data.setBoolean(TLMTags.Enable.tagName, false);
}
if (data.hasKey(TLMTags.Index.tagName)) {
data.removeTag(TLMTags.Index.tagName);
}
data.setInteger(TLMTags.State.tagName, State.None.ordinal());
itemStack.setTagCompound(data);
return itemStack;
public void updateGui() {
FluidCraft.proxy.netHandler.sendTo(
new SPacketLevelMaintainerGuiUpdate(this.tile.requests, !this.isFirstUpdate),
(EntityPlayerMP) this.getInventoryPlayer().player);
this.isFirstUpdate = false;
this.updateCount = 0;
}
}
@@ -1,30 +1,27 @@
package com.glodblock.github.client.gui.container;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.ForgeDirection;
import org.jetbrains.annotations.Nullable;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.api.registries.ILevelViewable;
import com.glodblock.github.api.registries.LevelItemInfo;
import com.glodblock.github.client.gui.container.base.FCBaseContainer;
import com.glodblock.github.common.parts.PartLevelTerminal;
import com.glodblock.github.coremod.registries.LevelTerminalRegistry;
import com.glodblock.github.inventory.item.IWirelessTerminal;
import com.glodblock.github.network.SPacketLevelTerminalUpdate;
import com.google.common.primitives.Ints;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridHost;
@@ -32,12 +29,7 @@ import appeng.api.networking.IGridNode;
import appeng.api.networking.security.IActionHost;
import appeng.api.storage.ITerminalHost;
import appeng.api.util.DimensionalCoord;
import appeng.helpers.InventoryAction;
import appeng.items.misc.ItemEncodedPattern;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.AdaptorPlayerHand;
import appeng.util.inv.ItemSlot;
public class ContainerLevelTerminal extends FCBaseContainer {
@@ -50,8 +42,8 @@ public class ContainerLevelTerminal extends FCBaseContainer {
private final Map<Long, ContainerLevelTerminal.InvTracker> trackedById = new HashMap<>();
private IGrid grid;
private SPacketLevelTerminalUpdate dirty;
private boolean isDirty;
private SPacketLevelTerminalUpdate updatePacket;
private boolean isPacketDirty;
private boolean wasOff;
private int ticks = 0;
@@ -63,11 +55,13 @@ public class ContainerLevelTerminal extends FCBaseContainer {
} else if (monitorable instanceof IWirelessTerminal wirelessTerminal) {
grid = wirelessTerminal.getActionableNode().getGrid();
}
dirty = this.updateList();
if (dirty != null) {
this.isDirty = true;
updatePacket = this.updateList();
if (updatePacket != null) {
this.isPacketDirty = true;
} else {
dirty = new SPacketLevelTerminalUpdate();
updatePacket = new SPacketLevelTerminalUpdate();
this.isPacketDirty = false;
}
}
@@ -92,7 +86,7 @@ public class ContainerLevelTerminal extends FCBaseContainer {
if (!wasOff) {
SPacketLevelTerminalUpdate update = new SPacketLevelTerminalUpdate();
update.setDisconnect();
update.addDisconnectEntry();
wasOff = true;
FluidCraft.proxy.netHandler.sendTo(update, (EntityPlayerMP) this.getPlayerInv().player);
}
@@ -100,149 +94,20 @@ public class ContainerLevelTerminal extends FCBaseContainer {
}
wasOff = false;
if (isDirty) {
FluidCraft.proxy.netHandler.sendTo(dirty, (EntityPlayerMP) this.getPlayerInv().player);
dirty = new SPacketLevelTerminalUpdate();
isDirty = false;
if (isPacketDirty) {
FluidCraft.proxy.netHandler.sendTo(updatePacket, (EntityPlayerMP) this.getPlayerInv().player);
updatePacket = new SPacketLevelTerminalUpdate();
isPacketDirty = false;
} else if (++ticks % 20 == 0) {
ticks = 0;
SPacketLevelTerminalUpdate update = this.updateList();
if (update != null) {
FluidCraft.proxy.netHandler.sendTo(update, (EntityPlayerMP) this.getPlayerInv().player);
SPacketLevelTerminalUpdate updateNew = this.updateList();
if (updateNew != null) {
FluidCraft.proxy.netHandler.sendTo(updateNew, (EntityPlayerMP) this.getPlayerInv().player);
}
}
}
/**
* Merge from slot -> player inv. Returns the items not added.
*/
private ItemStack mergeToPlayerInventory(InventoryAdaptor playerInv, ItemStack stack) {
if (stack == null) return null;
for (ItemSlot slot : playerInv) {
if (Platform.isSameItemPrecise(slot.getItemStack(), stack)) {
if (slot.getItemStack().stackSize < slot.getItemStack().getMaxStackSize()) {
++slot.getItemStack().stackSize;
return null;
}
}
}
return playerInv.addItems(stack);
}
@Override
public void doAction(final EntityPlayerMP player, final InventoryAction action, final int slotIdx, final long id) {
final ContainerLevelTerminal.InvTracker invTracker = this.trackedById.get(id);
if (invTracker != null) {
final ItemStack handStack = player.inventory.getItemStack();
if (handStack != null && !(handStack.getItem() instanceof ItemEncodedPattern)) {
// Why even bother if we're not dealing with an encoded pattern in hand
return;
}
final ItemStack slotStack = invTracker.requests.getStackInSlot(slotIdx);
final InventoryAdaptor playerHand = new AdaptorPlayerHand(player);
switch (action) {
/* Set down/pickup. This is the same as SPLIT_OR_PLACE_SINGLE as our max stack sizes are 1 in slots. */
case PICKUP_OR_SET_DOWN -> {
if (handStack != null) {
for (int s = 0; s < invTracker.requests.getSizeInventory(); s++) {
/* Is there a duplicate pattern here? */
if (Platform.isSameItemPrecise(invTracker.requests.getStackInSlot(s), handStack)) {
/* We're done here - dupe found. */
return;
}
}
}
if (slotStack == null) {
/* Insert to container, if valid */
if (handStack == null) {
/* Nothing happens */
return;
}
invTracker.requests.setInventorySlotContents(slotIdx, playerHand.removeItems(1, null, null));
} else {
/* Exchange? */
if (handStack != null && handStack.stackSize > 1) {
/* Exchange is impossible, abort */
return;
}
invTracker.requests.setInventorySlotContents(slotIdx, playerHand.removeItems(1, null, null));
playerHand.addItems(slotStack.copy());
}
syncLevelTerminalSlot(invTracker, id, slotIdx, invTracker.requests.getStackInSlot(slotIdx));
}
/* Shift click from slotIdx -> player. Player -> slotIdx is not supported. */
case SHIFT_CLICK -> {
InventoryAdaptor playerInv = InventoryAdaptor.getAdaptor(player.inventory, ForgeDirection.UNKNOWN);
ItemStack leftOver = mergeToPlayerInventory(playerInv, slotStack);
if (leftOver == null) {
invTracker.requests.setInventorySlotContents(slotIdx, null);
syncLevelTerminalSlot(invTracker, id, slotIdx, null);
}
}
/* Move all blank patterns -> player */
case MOVE_REGION -> {
final InventoryAdaptor playerInv = InventoryAdaptor.getAdaptor(player, ForgeDirection.UNKNOWN);
List<Integer> valid = new ArrayList<>();
for (int i = 0; i < invTracker.requests.getSizeInventory(); i++) {
ItemStack toExtract = invTracker.requests.getStackInSlot(i);
if (toExtract == null) {
continue;
}
ItemStack leftOver = mergeToPlayerInventory(playerInv, toExtract);
if (leftOver != null) {
break;
} else {
invTracker.requests.setInventorySlotContents(i, null);
}
valid.add(i);
}
if (!valid.isEmpty()) {
int[] validIndices = Ints.toArray(valid);
NBTTagList tag = new NBTTagList();
for (int i = 0; i < valid.size(); ++i) {
tag.appendTag(new NBTTagCompound());
}
dirty.addOverwriteEntry(id).setItems(validIndices, tag);
isDirty = true;
}
}
case CREATIVE_DUPLICATE -> {
if (player.capabilities.isCreativeMode) {
playerHand.addItems(handStack);
}
}
default -> {
return;
}
}
this.updateHeld(player);
}
}
private void syncLevelTerminalSlot(ContainerLevelTerminal.InvTracker inv, long id, int slot, ItemStack stack) {
int[] validIndices = { slot };
NBTTagList list = new NBTTagList();
NBTTagCompound item = new NBTTagCompound();
if (stack != null) {
stack.writeToNBT(item);
}
list.appendTag(item);
inv.updateNBT();
this.dirty.addOverwriteEntry(id).setItems(validIndices, list);
this.isDirty = true;
}
@Nullable
private SPacketLevelTerminalUpdate updateList() {
SPacketLevelTerminalUpdate update = null;
var supported = LevelTerminalRegistry.instance().getSupportedClasses();
@@ -257,64 +122,67 @@ public class ContainerLevelTerminal extends FCBaseContainer {
final ILevelViewable machine = isAdopted
? LevelTerminalRegistry.instance().getAdapter(clz).adapt(gridHost)
: (ILevelViewable) gridHost;
visited.add(gridHost);
/* First check if we are already tracking this node */
if (tracked.containsKey(gridHost)) {
/* Check for updates */
ContainerLevelTerminal.InvTracker knownTracker = tracked.get(gridHost);
/* Name changed? */
String name = machine.getCustomName();
if (!Objects.equals(knownTracker.name, name)) {
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addRenamedEntry(knownTracker.id, name);
knownTracker.name = name;
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addRenameEntry(knownTracker.id, name);
}
/* Status changed? */
boolean isActive = gridNode.isActive() || machine.shouldDisplay();
LevelItemInfo[] prev = knownTracker.infoList;
LevelItemInfo[] curr = machine.getLevelItemInfoList();
if (prev.length == curr.length) {
for (int i = 0; i < prev.length; i++) {
if (prev[i] == null && curr[i] == null) continue;
if (!knownTracker.online && isActive) {
/* Node offline -> online */
knownTracker.online = true;
if (update == null) update = new SPacketLevelTerminalUpdate();
knownTracker.updateNBT();
update.addOverwriteEntry(knownTracker.id).setOnline(true)
.setItems(knownTracker.requests.getSizeInventory(), knownTracker.inventoryNbt);
} else if (knownTracker.online && !isActive) {
/* Node online -> offline */
knownTracker.online = false;
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addOverwriteEntry(knownTracker.id).setOnline(false);
}
for (int i = 0; i < knownTracker.requests.getSizeInventory(); i++) {
ItemStack knowmItemStack = ItemStack
.loadItemStackFromNBT(knownTracker.inventoryNbt.getCompoundTagAt(i));
ItemStack machineItemStack = machine.getInventoryByName("config").getStackInSlot(i);
if (isDifferent(knowmItemStack, machineItemStack)) {
if (update == null) update = new SPacketLevelTerminalUpdate();
knownTracker.updateNBT();
update.addOverwriteEntry(knownTracker.id)
.setItems(knownTracker.requests.getSizeInventory(), knownTracker.inventoryNbt);
if (prev[i] == null) {
knownTracker.infoList[i] = curr[i];
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addOverwriteSlotEntry(knownTracker.id, i, curr[i]);
} else if (curr[i] == null) {
knownTracker.infoList[i] = null;
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addOverwriteSlotEntry(knownTracker.id, i, null);
} else if (!ItemStack.areItemStacksEqual(prev[i].stack, curr[i].stack)
|| prev[i].quantity == curr[i].quantity
|| prev[i].batchSize == curr[i].batchSize
|| prev[i].state == curr[i].state) {
knownTracker.infoList[i] = curr[i];
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addOverwriteSlotEntry(knownTracker.id, i, curr[i]);
}
}
} else {
knownTracker.infoList = curr;
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addOverwriteAllSlotEntry(knownTracker.id, curr);
}
} else {
/* Add a new entry */
if (update == null) update = new SPacketLevelTerminalUpdate();
ContainerLevelTerminal.InvTracker entry = new ContainerLevelTerminal.InvTracker(
nextId++,
machine,
gridNode.isActive());
update.addNewEntry(entry.id, entry.name, entry.online)
.setLocation(entry.x, entry.y, entry.z, entry.dim, entry.side.ordinal())
.setItems(entry.rows, entry.rowSize, entry.inventoryNbt)
.setViewItemStack(machine.getSelfItemStack(), machine.getDisplayItemStack());
ContainerLevelTerminal.InvTracker entry = new ContainerLevelTerminal.InvTracker(nextId++, machine);
update.addNewEntry(
entry.id,
entry.x,
entry.y,
entry.z,
entry.dim,
entry.side.ordinal(),
entry.rows,
entry.rowSize,
entry.name,
entry.infoList);
tracked.put(gridHost, entry);
trackedById.put(entry.id, entry);
}
visited.add(gridHost);
}
}
@@ -327,10 +195,9 @@ public class ContainerLevelTerminal extends FCBaseContainer {
}
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addRemoveEntry(entry.getValue().id);
trackedById.remove(entry.getValue().id);
it.remove();
update.addRemovalEntry(entry.getValue().id);
}
return update;
}
@@ -340,23 +207,10 @@ public class ContainerLevelTerminal extends FCBaseContainer {
return false;
}
private boolean isDifferent(final ItemStack a, final ItemStack b) {
if (a == null && b == null) {
return false;
}
if (a == null || b == null) {
return true;
}
return !ItemStack.areItemStacksEqual(a, b);
}
private static class InvTracker {
private final long id;
private String name;
private final IInventory requests;
private final int rowSize;
private final int rows;
private final int x;
@@ -364,16 +218,15 @@ public class ContainerLevelTerminal extends FCBaseContainer {
private final int z;
private final int dim;
private final ForgeDirection side;
private boolean online;
private NBTTagList inventoryNbt;
public InvTracker(long id, ILevelViewable machine, boolean online) {
private LevelItemInfo[] infoList;
public InvTracker(long id, ILevelViewable machine) {
DimensionalCoord location = machine.getLocation();
this.id = id;
this.name = machine.getCustomName();
this.requests = machine.getInventoryByName("config");
this.rowSize = machine.rowSize();
this.rows = machine.rows();
this.x = location.x;
@@ -381,26 +234,8 @@ public class ContainerLevelTerminal extends FCBaseContainer {
this.z = location.z;
this.dim = location.getDimension();
this.side = machine.getSide();
this.online = online;
this.inventoryNbt = new NBTTagList();
updateNBT();
this.infoList = machine.getLevelItemInfoList();
}
private void updateNBT() {
this.inventoryNbt = new NBTTagList();
for (int i = 0; i < this.rows; ++i) {
for (int j = 0; j < this.rowSize; ++j) {
final int offset = this.rowSize * i;
ItemStack stack = this.requests.getStackInSlot(offset + j);
if (stack != null) {
this.inventoryNbt.appendTag(stack.writeToNBT(new NBTTagCompound()));
} else {
this.inventoryNbt.appendTag(new NBTTagCompound());
}
}
}
}
}
}
@@ -4,7 +4,6 @@ import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import appeng.api.config.SecurityPermissions;
import appeng.api.storage.ITerminalHost;
import appeng.container.AEBaseContainer;
import appeng.container.guisync.GuiSync;
import appeng.container.slot.SlotInaccessible;
@@ -17,7 +16,7 @@ public class ContainerPatternValueAmount extends AEBaseContainer {
@GuiSync(11)
public int valueIndex;
public ContainerPatternValueAmount(final InventoryPlayer ip, final ITerminalHost te) {
public ContainerPatternValueAmount(final InventoryPlayer ip, final Object te) {
super(ip, te);
this.patternValue = new SlotInaccessible(new AppEngInternalInventory(null, 1), 0, 34, 53);
this.addSlotToContainer(patternValue);
@@ -0,0 +1,154 @@
package com.glodblock.github.client.gui.container;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.common.item.FCBaseItemCell;
import com.glodblock.github.common.tile.TileSuperStockReplenisher;
import com.glodblock.github.inventory.slot.OptionalFluidSlotFake;
import com.glodblock.github.network.SPacketSuperStockReplenisherUpdate;
import appeng.api.storage.data.IAEStack;
import appeng.container.AEBaseContainer;
import appeng.container.slot.IOptionalSlotHost;
import appeng.container.slot.SlotPatternOutputs;
import appeng.container.slot.SlotRestrictedInput;
import appeng.items.storage.ItemBasicStorageCell;
import appeng.util.item.AEItemStack;
public class ContainerSuperStockReplenisher extends AEBaseContainer implements IOptionalSlotHost {
private final TileSuperStockReplenisher tile;
private final IInventory configFluids;
private final IInventory configItems;
private int lastUpdated = 0;
public ContainerSuperStockReplenisher(InventoryPlayer ipl, TileSuperStockReplenisher tile) {
super(ipl, tile);
this.tile = tile;
configFluids = tile.getConfigFluid();
configItems = tile.getConfigItems();
final IInventory cell = tile.getCell();
final int x = 8;
final int fy = 8;
this.addSlotToContainer(
new SlotRestrictedInput(
SlotRestrictedInput.PlacableItemType.WORKBENCH_CELL,
cell,
0,
173,
fy,
this.getInventoryPlayer()));
for (int i = 0; i < 9; i++) {
addSlotToContainer(new OptionalFluidSlotFake(configFluids, this, i, x, fy, i, 0, 0));
}
final int io = 29;
for (int y = 0; y < 7; y++) {
for (int ix = 0; ix < 9; ix++) {
this.addSlotToContainer(new SlotPatternOutputs(configItems, this, y * 9 + ix, x, io, ix, y, y));
}
}
bindPlayerInventory(ipl, 0, 251 - 82);
}
@Override
public ItemStack slotClick(int slotId, int clickedButton, int mode, EntityPlayer player) {
if (slotId == 0 && player.inventory.getItemStack() == null && isConfigurated()) {
return null;
}
return super.slotClick(slotId, clickedButton, mode, player);
}
@Override
public boolean isSlotEnabled(int idx) {
return true;
}
@Override
public void addCraftingToCrafters(ICrafting p_75132_1_) {
super.addCraftingToCrafters(p_75132_1_);
lastUpdated = 24;
}
@Override
public void detectAndSendChanges() {
super.detectAndSendChanges();
if (lastUpdated > 20) {
lastUpdated = 0;
Map<Integer, IAEStack<?>> tmp = new HashMap<>();
for (int i = 0; i < tile.getInternalFluid().getSlots(); i++) {
tmp.put(i, tile.getInternalFluid().getFluidInSlot(i));
}
for (int i = 0; i < tile.getInternalInventory().getSizeInventory(); i++) {
tmp.put(i + 100, AEItemStack.create(tile.getInternalInventory().getStackInSlot(i)));
}
for (final Object g : this.crafters) {
if (g instanceof EntityPlayer) {
FluidCraft.proxy.netHandler.sendTo(new SPacketSuperStockReplenisherUpdate(tmp), (EntityPlayerMP) g);
}
}
}
lastUpdated++;
}
private boolean isConfigurated() {
for (int i = 0; i < configItems.getSizeInventory(); i++) {
if (configItems.getStackInSlot(i) != null) {
return true;
}
}
for (int i = 0; i < configFluids.getSizeInventory(); i++) {
if (configFluids.getStackInSlot(i) != null) {
return true;
}
}
return false;
}
@Override
public boolean isValidForSlot(Slot s, ItemStack is) {
if (s.slotNumber == 0 && s.getHasStack() && isConfigurated()) {
long currentBytes = 0;
long newBytes = -1;
if (s.getStack().getItem() instanceof ItemBasicStorageCell ibsc) {
currentBytes = ibsc.getBytesLong(is);
} else if (s.getStack().getItem() instanceof FCBaseItemCell fcbic) {
currentBytes = fcbic.getBytes(is);
}
if (is.getItem() instanceof ItemBasicStorageCell ibsc) {
newBytes = ibsc.getBytesLong(is);
} else if (is.getItem() instanceof FCBaseItemCell fcbic) {
newBytes = fcbic.getBytes(is);
}
if (currentBytes > newBytes) {
return false;
}
}
return super.isValidForSlot(s, is);
}
public TileSuperStockReplenisher getTile() {
return tile;
}
}
@@ -1,6 +1,8 @@
package com.glodblock.github.client.gui.container.base;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
@@ -10,10 +12,15 @@ import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ICrafting;
import net.minecraft.item.ItemStack;
import com.glodblock.github.inventory.item.BaseWirelessInventory;
import com.glodblock.github.inventory.item.IWirelessTerminal;
import com.glodblock.github.network.SPacketMEUpdateBuffer;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import appeng.api.config.Actionable;
import appeng.api.config.CraftingAllow;
import appeng.api.config.PinsState;
import appeng.api.config.PowerMultiplier;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings;
@@ -22,10 +29,16 @@ import appeng.api.config.SortOrder;
import appeng.api.config.TypeFilter;
import appeng.api.config.ViewItems;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingCPU;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.security.PlayerSource;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.ITerminalPins;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
@@ -34,18 +47,22 @@ import appeng.container.slot.SlotRestrictedInput;
import appeng.core.AELog;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.helpers.IPinsHandler;
import appeng.helpers.WirelessTerminalGuiObject;
import appeng.items.contents.PinsHandler;
import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.Platform;
public abstract class FCContainerMonitor<T extends IAEStack<T>> extends FCBaseContainer
implements IConfigManagerHost, IConfigurableObject, IMEMonitorHandlerReceiver<T> {
implements IConfigManagerHost, IConfigurableObject, IMEMonitorHandlerReceiver<T>, IPinsHandler {
protected final SlotRestrictedInput[] cellView = new SlotRestrictedInput[5];
protected final IConfigManager clientCM;
protected final ITerminalHost host;
protected PinsHandler pinsHandler = null;
@GuiSync(99)
public boolean canAccessViewCells = false;
@@ -70,6 +87,14 @@ public abstract class FCContainerMonitor<T extends IAEStack<T>> extends FCBaseCo
this.clientCM.registerSetting(Settings.VIEW_MODE, ViewItems.ALL);
this.clientCM.registerSetting(Settings.SORT_DIRECTION, SortDir.ASCENDING);
this.clientCM.registerSetting(Settings.TYPE_FILTER, TypeFilter.ALL);
this.clientCM.registerSetting(Settings.PINS_STATE, PinsState.DISABLED); // use for GUI
if (Platform.isServer()) {
if (monitorable instanceof ITerminalPins t && !(monitorable instanceof BaseWirelessInventory bwi
&& bwi.getChannel() == StorageChannel.FLUIDS)) {
pinsHandler = t.getPinsHandler(ip.player);
}
}
}
public IMEMonitor<T> getMonitor() {
@@ -105,6 +130,16 @@ public abstract class FCContainerMonitor<T extends IAEStack<T>> extends FCBaseCo
}
}
}
if (pinsHandler != null) {
if (clientCM.getSetting(Settings.PINS_STATE) != pinsHandler.getPinsState()) {
this.clientCM.putSetting(Settings.PINS_STATE, pinsHandler.getPinsState());
updatePins(true);
} else {
updatePins(false);
}
}
processItemList();
this.updatePowerStatus();
final boolean oldAccessible = this.canAccessViewCells;
@@ -122,6 +157,84 @@ public abstract class FCContainerMonitor<T extends IAEStack<T>> extends FCBaseCo
}
}
private int lastUpdate = 0;
public void updatePins(boolean forceUpdate) {
if (pinsHandler == null || !(host instanceof ITerminalPins itp)) return;
boolean isActive = pinsHandler.getPinsState() != PinsState.DISABLED;
++lastUpdate;
if (!forceUpdate && lastUpdate <= 20) return;
lastUpdate = 0;
if (isActive) {
final ICraftingGrid cc = itp.getGrid().getCache(ICraftingGrid.class);
final ImmutableList<ICraftingCPU> cpuList = cc.getCpus().asList();
List<IAEItemStack> craftedItems = new ArrayList<>();
// fetch the first available crafting output
for (int i = 0; i < cpuList.size(); i++) {
ICraftingCPU cpu = cpuList.get(i);
if (cpu.getCraftingAllowMode() != CraftingAllow.ONLY_NONPLAYER && cpu.getFinalOutput() != null
&& cpu.getCurrentJobSource() instanceof PlayerSource src
&& src.player == pinsHandler.getPlayer()) {
if (craftedItems.contains(cpu.getFinalOutput())) {
continue; // skip if already added
}
if (cpu.isBusy()) craftedItems.add(0, cpu.getFinalOutput().copy());
else craftedItems.add(cpu.getFinalOutput().copy());
}
}
pinsHandler.addItemsToPins(craftedItems);
}
pinsHandler.update(forceUpdate);
onListUpdate(); // notify the repo that the pins have changed
}
@Override
public void setPin(ItemStack is, int idx) {
if (pinsHandler == null || !(host instanceof ITerminalPins itp)) return;
if (is == null) {
final ICraftingGrid cc = itp.getGrid().getCache(ICraftingGrid.class);
final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus();
for (ICraftingCPU cpu : cpuSet) {
if (cpu.getCraftingAllowMode() != CraftingAllow.ONLY_NONPLAYER && cpu.getFinalOutput() != null
&& cpu.getFinalOutput().isSameType(getPin(idx))) {
if (!cpu.isBusy()) {
cpu.resetFinalOutput();
} else {
return;
}
}
}
}
pinsHandler.setPin(idx, is);
updatePins(true);
}
@Override
public ItemStack getPin(int idx) {
if (pinsHandler == null) return null;
return pinsHandler.getPin(idx);
}
public void setPinsState(PinsState pinsState) {
if (pinsHandler == null) return;
clientCM.putSetting(Settings.PINS_STATE, pinsState);
pinsHandler.setPinsState(pinsState);
updatePins(true);
}
public PinsState getPinsState() {
return pinsHandler != null ? pinsHandler.getPinsState() : PinsState.DISABLED;
}
public PinsHandler getPinsHandler() {
return pinsHandler;
}
protected abstract void processItemList();
protected boolean isInvalid() {
@@ -0,0 +1,66 @@
package com.glodblock.github.common.block;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import com.glodblock.github.common.tabs.FluidCraftingTabs;
import com.glodblock.github.common.tile.TileSuperStockReplenisher;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.util.BlockPos;
import com.glodblock.github.util.NameConst;
import appeng.block.AEBaseItemBlock;
import cpw.mods.fml.common.registry.GameRegistry;
public class BlockSuperStockReplenisher extends FCBaseBlock {
public BlockSuperStockReplenisher() {
super(Material.web, NameConst.BLOCK_SUPER_STOCK_REPLENISHER);
setTileEntity(TileSuperStockReplenisher.class);
setOpaque(true);
setFullBlock(true);
this.lightOpacity = 4;
}
@Override
public boolean onActivated(World world, int x, int y, int z, EntityPlayer player, int facing, float hitX,
float hitY, float hitZ) {
if (player.isSneaking()) {
return false;
}
TileSuperStockReplenisher tile = getTileEntity(world, x, y, z);
if (tile != null) {
if (!world.isRemote) {
InventoryHandler.openGui(
player,
world,
new BlockPos(x, y, z),
ForgeDirection.getOrientation(facing),
GuiType.GUI_SUPER_STOCK_REPLENISHER);
}
return true;
}
return false;
}
@Override
public void breakBlock(World w, int x, int y, int z, Block a, int b) {
final TileSuperStockReplenisher tss = this.getTileEntity(w, x, y, z);
if (tss != null) {
tss.fullRefund();
}
super.breakBlock(w, x, y, z, a, b);
}
@Override
public BlockSuperStockReplenisher register() {
GameRegistry.registerBlock(this, AEBaseItemBlock.class, NameConst.BLOCK_SUPER_STOCK_REPLENISHER);
GameRegistry.registerTileEntity(TileSuperStockReplenisher.class, NameConst.BLOCK_SUPER_STOCK_REPLENISHER);
setCreativeTab(FluidCraftingTabs.INSTANCE);
return this;
}
}
@@ -20,6 +20,7 @@ import com.glodblock.github.common.storage.CellType;
import com.glodblock.github.common.storage.FluidCellInventory;
import com.glodblock.github.common.storage.FluidCellInventoryHandler;
import com.glodblock.github.common.storage.IStorageFluidCell;
import com.glodblock.github.inventory.FluidCellConfig;
import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.util.NameConst;
import com.google.common.base.Optional;
@@ -36,7 +37,6 @@ import appeng.core.features.AEFeature;
import appeng.core.localization.GuiText;
import appeng.helpers.ICellRestriction;
import appeng.items.AEBaseItem;
import appeng.items.contents.CellConfig;
import appeng.items.contents.CellUpgrades;
import appeng.util.InventoryAdaptor;
import appeng.util.IterationCounter;
@@ -208,7 +208,7 @@ public abstract class FCBaseItemCell extends AEBaseItem implements IStorageFluid
@Override
public IInventory getConfigInventory(ItemStack is) {
return new CellConfig(is);
return new FluidCellConfig(is);
}
@Override
@@ -54,19 +54,19 @@ public class ItemBaseWirelessTerminal extends ToolWirelessTerminal implements II
}
IWirelessTermRegistry term = AEApi.instance().registries().wireless();
if (!term.isWirelessTerminal(item)) {
player.addChatMessage(PlayerMessages.DeviceNotWirelessTerminal.get());
player.addChatMessage(PlayerMessages.DeviceNotWirelessTerminal.toChat());
return item;
}
final IWirelessTermHandler handler = term.getWirelessTerminalHandler(item);
final String unparsedKey = handler.getEncryptionKey(item);
if (unparsedKey.isEmpty()) {
player.addChatMessage(PlayerMessages.DeviceNotLinked.get());
player.addChatMessage(PlayerMessages.DeviceNotLinked.toChat());
return item;
}
final long parsedKey = Long.parseLong(unparsedKey);
final ILocatable securityStation = AEApi.instance().registries().locatable().getLocatableBy(parsedKey);
if (securityStation == null) {
player.addChatMessage(PlayerMessages.StationCanNotBeLocated.get());
player.addChatMessage(PlayerMessages.StationCanNotBeLocated.toChat());
return item;
}
if (handler.hasPower(player, 0.5, item)) {
@@ -77,7 +77,7 @@ public class ItemBaseWirelessTerminal extends ToolWirelessTerminal implements II
ForgeDirection.UNKNOWN,
this.guiGuiType(item));
} else {
player.addChatMessage(PlayerMessages.DeviceNotPowered.get());
player.addChatMessage(PlayerMessages.DeviceNotPowered.toChat());
}
}
@@ -8,12 +8,12 @@ import net.minecraft.item.ItemStack;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.common.storage.IStorageFluidCell;
import com.glodblock.github.common.tabs.FluidCraftingTabs;
import com.glodblock.github.inventory.FluidCellConfig;
import com.glodblock.github.loader.IRegister;
import com.glodblock.github.util.NameConst;
import appeng.api.config.FuzzyMode;
import appeng.core.features.AEFeature;
import appeng.items.contents.CellConfig;
import appeng.util.Platform;
import cpw.mods.fml.common.registry.GameRegistry;
@@ -30,7 +30,7 @@ public class ItemCreativeFluidStorageCell extends ItemBaseInfinityStorageCell
@Override
public IInventory getConfigInventory(ItemStack is) {
return new CellConfig(is);
return new FluidCellConfig(is);
}
@Override
@@ -14,6 +14,7 @@ import com.glodblock.github.common.storage.IFluidCellInventory;
import com.glodblock.github.common.storage.IFluidCellInventoryHandler;
import com.glodblock.github.common.storage.IStorageFluidCell;
import com.glodblock.github.common.tabs.FluidCraftingTabs;
import com.glodblock.github.inventory.FluidCellConfig;
import com.glodblock.github.loader.IRegister;
import com.glodblock.github.util.NameConst;
@@ -25,7 +26,6 @@ import appeng.api.storage.data.IAEFluidStack;
import appeng.core.features.AEFeature;
import appeng.core.localization.GuiText;
import appeng.items.AEBaseItem;
import appeng.items.contents.CellConfig;
import appeng.items.contents.CellUpgrades;
import appeng.util.Platform;
import cpw.mods.fml.common.registry.GameRegistry;
@@ -116,7 +116,7 @@ public class ItemFluidVoidStorageCell extends AEBaseItem
@Override
public IInventory getConfigInventory(ItemStack is) {
return new CellConfig(is);
return new FluidCellConfig(is);
}
@Override
@@ -20,6 +20,7 @@ import com.glodblock.github.common.storage.IFluidCellInventory;
import com.glodblock.github.common.storage.IFluidCellInventoryHandler;
import com.glodblock.github.common.storage.IStorageFluidCell;
import com.glodblock.github.common.tabs.FluidCraftingTabs;
import com.glodblock.github.inventory.FluidCellConfig;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.inventory.item.IItemInventory;
@@ -37,7 +38,6 @@ import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.core.features.AEFeature;
import appeng.core.localization.GuiText;
import appeng.items.contents.CellConfig;
import appeng.items.contents.CellUpgrades;
import appeng.items.tools.powered.powersink.AEBasePoweredItem;
import appeng.util.Platform;
@@ -163,7 +163,7 @@ public class ItemPortableFluidCell extends AEBasePoweredItem
@Override
public IInventory getConfigInventory(final ItemStack is) {
return new CellConfig(is);
return new FluidCellConfig(is);
}
@Override
@@ -44,7 +44,7 @@ public class ItemWirelessFluidTerminal extends ItemBaseWirelessTerminal
IGridNode gridNode = Util.getWirelessGrid(stack);
return new WirelessFluidTerminalInventory(stack, x, gridNode, player);
} catch (Exception e) {
player.addChatMessage(PlayerMessages.OutOfRange.get());
player.addChatMessage(PlayerMessages.OutOfRange.toChat());
}
return null;
}
@@ -44,7 +44,7 @@ public class ItemWirelessInterfaceTerminal extends ItemBaseWirelessTerminal
IGridNode gridNode = Util.getWirelessGrid(stack);
return new WirelessInterfaceTerminalInventory(stack, x, gridNode, player);
} catch (Exception e) {
player.addChatMessage(PlayerMessages.OutOfRange.get());
player.addChatMessage(PlayerMessages.OutOfRange.toChat());
}
return null;
}
@@ -44,7 +44,7 @@ public class ItemWirelessLevelTerminal extends ItemBaseWirelessTerminal
IGridNode gridNode = Util.getWirelessGrid(stack);
return new WirelessLevelTerminalInventory(stack, x, gridNode, player);
} catch (Exception e) {
player.addChatMessage(PlayerMessages.OutOfRange.get());
player.addChatMessage(PlayerMessages.OutOfRange.toChat());
}
return null;
}
@@ -44,7 +44,7 @@ public class ItemWirelessPatternTerminal extends ItemBaseWirelessTerminal
IGridNode gridNode = Util.getWirelessGrid(stack);
return new WirelessPatternTerminalInventory(stack, x, gridNode, player);
} catch (Exception e) {
player.addChatMessage(PlayerMessages.OutOfRange.get());
player.addChatMessage(PlayerMessages.OutOfRange.toChat());
}
return null;
}
@@ -135,7 +135,7 @@ public class ItemWirelessUltraTerminal extends ItemBaseWirelessTerminal
return new WirelessFluidTerminalInventory(stack, x, gridNode, player);
}
} catch (Exception e) {
player.addChatMessage(PlayerMessages.OutOfRange.get());
player.addChatMessage(PlayerMessages.OutOfRange.toChat());
}
return null;
}
@@ -274,9 +274,9 @@ public class ItemWirelessUltraTerminal extends ItemBaseWirelessTerminal
@Override
public void onUpdate(ItemStack stack, World worldIn, Entity entityIn, int slot, boolean p_77663_5_) {
if (Platform.isServer() && entityIn instanceof EntityPlayer player) {
if (entityIn instanceof EntityPlayer player) {
if (WirelessMagnet.getMode(stack) != WirelessMagnet.Mode.Off) {
WirelessMagnet.doMagnet(stack, player.worldObj, player);
WirelessMagnet.doMagnet(stack, player);
}
}
}
@@ -114,10 +114,9 @@ public class PartFluidExportBus extends FCSharedFluidBus implements ICraftingReq
this.didSomething = false;
this.fluidToSend = this.calculateAmountToSend();
final TileEntity te = this.getConnectedTE();
if (te instanceof IFluidHandler) {
InventoryAdaptor destination;
if (te instanceof IFluidHandler && (destination = this.getHandler(te)) != null) {
try {
final InventoryAdaptor destination = this.getHandler(te);
final ICraftingGrid cg = this.getProxy().getCrafting();
final IFluidHandler fh = (IFluidHandler) te;
final IMEMonitor<IAEFluidStack> inv = this.getProxy().getStorage().getFluidInventory();
@@ -18,6 +18,8 @@ import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.FluidStack;
import com.glodblock.github.api.registries.ILevelViewable;
import com.glodblock.github.api.registries.LevelItemInfo;
import com.glodblock.github.api.registries.LevelState;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
@@ -314,9 +316,10 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
@SideOnly(Side.CLIENT)
public void renderInventory(final IPartRenderHelper rh, final RenderBlocks renderer) {
rh.setTexture(this.getItemStack().getIconIndex());
Tessellator.instance.startDrawingQuads();
final Tessellator tess = Tessellator.instance;
tess.startDrawingQuads();
this.renderTorchAtAngle(0, -0.5, 0);
Tessellator.instance.draw();
tess.draw();
}
private void renderTorchAtAngle(double baseX, double baseY, double baseZ) {
@@ -586,4 +589,15 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
return super.getInventoryByName(name);
}
@Override
public LevelItemInfo[] getLevelItemInfoList() {
ItemStack stack = this.config.getStackInSlot(0);
if (stack == null) return new LevelItemInfo[] { null };
return new LevelItemInfo[] { new LevelItemInfo(
stack,
this.getReportingValue(),
-1,
this.isProvidingStrongPower() > 0 ? LevelState.Craft : LevelState.Idle) };
}
}
@@ -1,5 +1,7 @@
package com.glodblock.github.common.parts;
import static appeng.helpers.DualityInterface.NUMBER_OF_STORAGE_SLOTS;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
@@ -56,6 +58,7 @@ import appeng.helpers.DualityInterface;
import appeng.helpers.IInterfaceHost;
import appeng.helpers.IPriorityHost;
import appeng.me.GridAccessException;
import appeng.me.cache.CraftingGridCache;
import appeng.parts.automation.UpgradeInventory;
import appeng.parts.p2p.PartP2PTunnel;
import appeng.parts.p2p.PartP2PTunnelStatic;
@@ -64,28 +67,45 @@ import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.IAEAppEngInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.Platform;
import appeng.util.inv.AdaptorIInventory;
import appeng.util.inv.IInventoryDestination;
import appeng.util.inv.WrapperInvSlot;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class PartFluidP2PInterface extends PartP2PTunnelStatic<PartFluidP2PInterface>
implements IGridTickable, IStorageMonitorable, IInventoryDestination, IDualHost, ISidedInventory,
IAEAppEngInventory, ITileStorageMonitorable, IPriorityHost, IInterfaceHost {
boolean needUpdateOnNetworkBooted = false;
boolean lastPowerStart = false;
public PartFluidP2PInterface(ItemStack is) {
super(is);
}
private final DualityInterface duality = new DualityInterface(this.getProxy(), this) {
@Override
public void updateCraftingList() {
if (!isOutput()) {
CraftingGridCache.pauseRebuilds();
super.updateCraftingList();
try {
for (PartFluidP2PInterface p2p : getOutputs()) p2p.duality.updateCraftingList();
for (PartFluidP2PInterface p2p : getOutputs()) {
p2p.duality.updateCraftingList();
}
} catch (GridAccessException e) {
// ?
}
CraftingGridCache.unpauseRebuilds();
} else {
PartFluidP2PInterface p2p = getInput();
if (p2p != null) {
this.craftingList = p2p.duality.craftingList;
try {
this.gridProxy.getGrid()
.postEvent(new MENetworkCraftingPatternChange(this, this.gridProxy.getNode()));
@@ -96,29 +116,165 @@ public class PartFluidP2PInterface extends PartP2PTunnelStatic<PartFluidP2PInter
}
}
@Override
public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLastCall) {
final boolean powerState = proxy.isActive();
if (needUpdateOnNetworkBooted || lastPowerStart != powerState) {
needUpdateOnNetworkBooted = false;
lastPowerStart = powerState;
updateSharingInventory();
}
return super.tickingRequest(node, ticksSinceLastCall);
}
@Override
protected boolean hasWorkToDo() {
if (isOutput()) {
return hasItemsToSend() || hasConfig() || !getStorage().isEmpty();
} else return super.hasWorkToDo();
}
@Override
public void readConfig() {
if (isOutput()) {
PartFluidP2PInterface p2p = getInput();
boolean alertDevice = false;
if (p2p != null) {
this.setHasConfig(p2p.duality.hasConfig());
alertDevice = hasWorkToDo();
} else {
this.setHasConfig(false);
}
if (alertDevice) {
try {
this.gridProxy.getTick().alertDevice(this.gridProxy.getNode());
} catch (final GridAccessException ignored) {}
} else {
try {
this.gridProxy.getTick().sleepDevice(this.gridProxy.getNode());
} catch (final GridAccessException ignored) {}
}
this.notifyNeighbors();
} else {
super.readConfig();
}
}
@Override
public void addDrops(final List<ItemStack> drops) {
if (!isOutput()) {
super.addDrops(drops);
try {
for (PartFluidP2PInterface p2p : getOutputs()) p2p.duality.addDrops(drops);
} catch (GridAccessException ignored) {}
} else {
if (this.getWaitingToSend() != null) {
for (final ItemStack is : this.getWaitingToSend()) {
if (is != null) {
drops.add(is);
}
}
}
for (final ItemStack is : this.getUpgrades()) {
if (is != null) {
drops.add(is);
}
}
for (final ItemStack is : this.getPatterns()) {
if (is != null) {
drops.add(is);
}
}
}
}
@Override
public int getInstalledUpgrades(Upgrades u) {
if (isOutput() && u == Upgrades.PATTERN_CAPACITY) return -1;
return super.getInstalledUpgrades(u);
}
@Override
public int getConfigSize() {
if (isOutput()) return -1;
return super.getConfigSize();
}
};
private final DualityFluidInterface dualityFluid = new DualityFluidInterface(this.getProxy(), this);
private final AppEngInternalAEInventory config = new AppEngInternalAEInventory(this, 6);
public PartFluidP2PInterface(ItemStack is) {
super(is);
private void updateSharingInventory() {
duality.readConfig();
if (isOutput()) {
PartFluidP2PInterface p2p = getInput();
if (proxy.isActive() && p2p != null) {
if (!duality.sharedInventory && !duality.getStorage().isEmpty()) {
ArrayList<ItemStack> drops = new ArrayList<>();
AppEngInternalInventory storageAppEng = this.duality.getStorage();
AdaptorIInventory p2pInv = new AdaptorIInventory(p2p.duality.getStorage());
for (ItemStack itemStack : storageAppEng) {
if (itemStack == null) continue;
ItemStack drop = p2pInv.addItems(itemStack);
if (drop != null && drop.stackSize > 0) {
drops.add(drop);
}
}
TileEntity te = getTileEntity();
Platform.spawnDrops(te.getWorldObj(), te.xCoord, te.yCoord, te.zCoord, drops);
}
duality.setStorage(p2p.duality.getStorage());
duality.sharedInventory = true;
} else {
if (duality.sharedInventory) {
duality.setStorage(new AppEngInternalInventory(this, NUMBER_OF_STORAGE_SLOTS));
duality.setSlotInv(new WrapperInvSlot(duality.getStorage()));
duality.sharedInventory = false;
}
}
} else {
if (duality.sharedInventory) {
duality.setStorage(new AppEngInternalInventory(this, NUMBER_OF_STORAGE_SLOTS));
duality.setSlotInv(new WrapperInvSlot(duality.getStorage()));
duality.sharedInventory = false;
}
try {
for (PartFluidP2PInterface p2p : getOutputs()) {
p2p.duality.readConfig();
}
} catch (GridAccessException ignored) {}
}
}
@MENetworkEventSubscribe
public void stateChange(final MENetworkChannelsChanged c) {
dualityFluid.onChannelStateChange(c);
duality.notifyNeighbors();
this.duality.notifyNeighbors();
updateSharingInventory();
needUpdateOnNetworkBooted = true;
}
@MENetworkEventSubscribe
public void stateChange(final MENetworkPowerStatusChange c) {
dualityFluid.onPowerStateChange(c);
duality.notifyNeighbors();
this.duality.notifyNeighbors();
updateSharingInventory();
needUpdateOnNetworkBooted = true;
}
@Override
public int getInstalledUpgrades(final Upgrades u) {
return this.duality.getInstalledUpgrades(u);
}
@Override
@SideOnly(Side.CLIENT)
public IIcon getTypeTexture() {
return ItemAndBlockHolder.INTERFACE.getBlockTextureFromSide(0);
}
@Override
@@ -127,20 +283,73 @@ public class PartFluidP2PInterface extends PartP2PTunnelStatic<PartFluidP2PInter
dualityFluid.gridChanged();
}
@Override
public void readFromNBT(final NBTTagCompound data) {
super.readFromNBT(data);
this.duality.readFromNBT(data);
}
@Override
public void writeToNBT(final NBTTagCompound data) {
super.writeToNBT(data);
this.duality.writeToNBT(data);
}
@Override
public NBTTagCompound getMemoryCardData() {
final NBTTagCompound output = super.getMemoryCardData();
this.duality.getConfigManager().writeToNBT(output);
return output;
}
@Override
public void pasteMemoryCardData(PartP2PTunnel<?> newTunnel, NBTTagCompound data) throws GridAccessException {
this.duality.getConfigManager().readFromNBT(data);
super.pasteMemoryCardData(newTunnel, data);
}
@Override
public void addToWorld() {
super.addToWorld();
this.duality.initialize();
}
@Override
public void getDrops(final List<ItemStack> drops, final boolean wrenched) {
this.duality.addDrops(drops);
}
@Override
public int cableConnectionRenderTo() {
return 4;
}
@Override
public IConfigManager getConfigManager() {
return this.duality.getConfigManager();
}
@Override
public IInventory getInventoryByName(final String name) {
return this.duality.getInventoryByName(name);
}
@Override
public void onNeighborChanged() {
this.duality.updateRedstoneState();
}
@Override
public boolean onPartActivate(final EntityPlayer player, final Vec3 pos) {
AppEngInternalInventory patterns = (AppEngInternalInventory) duality.getPatterns();
if (super.onPartActivate(player, pos)) {
public boolean onPartActivate(final EntityPlayer p, final Vec3 pos) {
AppEngInternalInventory patterns = this.duality.getPatterns();
if (super.onPartActivate(p, pos)) {
ArrayList<ItemStack> drops = new ArrayList<>();
for (int i = 0; i < patterns.getSizeInventory(); i++) {
if (patterns.getStackInSlot(i) == null) continue;
drops.add(patterns.getStackInSlot(i));
}
final IPart tile = this.getHost().getPart(this.getSide());
if (tile instanceof PartFluidP2PInterface dualTile) {
DualityInterface newDuality = dualTile.duality;
@@ -151,11 +360,15 @@ public class PartFluidP2PInterface extends PartP2PTunnelStatic<PartFluidP2PInter
for (int i = 0; i < upgrades.getSizeInventory(); ++i) {
newUpgrade.setInventorySlotContents(i, upgrades.getStackInSlot(i));
}
IInventory storage = duality.getStorage();
IInventory newStorage = newDuality.getStorage();
for (int i = 0; i < storage.getSizeInventory(); ++i) {
newStorage.setInventorySlotContents(i, storage.getStackInSlot(i));
if (!duality.sharedInventory) {
IInventory storage = duality.getStorage();
IInventory newStorage = newDuality.getStorage();
for (int i = 0; i < storage.getSizeInventory(); ++i) {
newStorage.setInventorySlotContents(i, storage.getStackInSlot(i));
}
}
IConfigManager config = duality.getConfigManager();
config.getSettings().forEach(
setting -> newDuality.getConfigManager().putSetting(setting, config.getSetting(setting)));
@@ -166,13 +379,13 @@ public class PartFluidP2PInterface extends PartP2PTunnelStatic<PartFluidP2PInter
return true;
}
if (player.isSneaking()) {
if (p.isSneaking()) {
return false;
}
if (Platform.isServer()) {
InventoryHandler.openGui(
player,
p,
this.getHost().getTile().getWorldObj(),
new BlockPos(this.getHost().getTile()),
Objects.requireNonNull(this.getSide()),
@@ -183,13 +396,23 @@ public class PartFluidP2PInterface extends PartP2PTunnelStatic<PartFluidP2PInter
}
@Override
public IIcon getTypeTexture() {
return ItemAndBlockHolder.INTERFACE.getBlockTextureFromSide(0);
public IIcon getBreakingTexture() {
return this.getItemStack().getIconIndex();
}
@Override
public IStorageMonitorable getMonitorable(ForgeDirection side, BaseActionSource src) {
return duality.getMonitorable(side, src, this);
public boolean canInsert(final ItemStack stack) {
return this.duality.canInsert(stack);
}
@Override
public IMEMonitor<IAEItemStack> getItemInventory() {
return this.duality.getItemInventory();
}
@Override
public IMEMonitor<IAEFluidStack> getFluidInventory() {
return this.duality.getFluidInventory();
}
@Override
@@ -214,142 +437,216 @@ public class PartFluidP2PInterface extends PartP2PTunnelStatic<PartFluidP2PInter
}
}
@Override
public int getInstalledUpgrades(Upgrades u) {
return duality.getInstalledUpgrades(u);
}
@Override
public IMEMonitor<IAEItemStack> getItemInventory() {
return duality.getItemInventory();
}
@Override
public IMEMonitor<IAEFluidStack> getFluidInventory() {
return duality.getFluidInventory();
}
@Override
public int getPriority() {
return duality.getPriority();
}
@Override
public void setPriority(int newValue) {
duality.setPriority(newValue);
}
@Override
public void onTunnelNetworkChange() {
duality.updateCraftingList();
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation op, ItemStack removedStack,
ItemStack newStack) {
duality.onChangeInventory(inv, slot, op, removedStack, newStack);
}
@Override
public boolean canInsert(ItemStack stack) {
return duality.canInsert(stack);
}
@Override
public int getSizeInventory() {
return duality.getStorage().getSizeInventory();
return this.duality.getStorage().getSizeInventory();
}
@Override
public ItemStack getStackInSlot(int slotIn) {
return duality.getStorage().getStackInSlot(slotIn);
public ItemStack getStackInSlot(final int i) {
return this.duality.getStorage().getStackInSlot(i);
}
@Override
public ItemStack decrStackSize(int index, int count) {
return duality.getStorage().decrStackSize(index, count);
public ItemStack decrStackSize(final int i, final int j) {
return this.duality.getStorage().decrStackSize(i, j);
}
@Override
public ItemStack getStackInSlotOnClosing(int index) {
return duality.getStorage().getStackInSlotOnClosing(index);
public ItemStack getStackInSlotOnClosing(final int i) {
return this.duality.getStorage().getStackInSlotOnClosing(i);
}
@Override
public void setInventorySlotContents(int index, ItemStack stack) {
duality.getStorage().setInventorySlotContents(index, stack);
}
@Override
public IInventory getInventoryByName(String name) {
return duality.getInventoryByName(name);
}
@Override
public IConfigManager getConfigManager() {
return duality.getConfigManager();
}
@Override
public IIcon getBreakingTexture() {
return getItemStack().getIconIndex();
public void setInventorySlotContents(final int i, final ItemStack itemstack) {
this.duality.getStorage().setInventorySlotContents(i, itemstack);
}
@Override
public String getInventoryName() {
return duality.getStorage().getInventoryName();
return this.duality.getStorage().getInventoryName();
}
@Override
public boolean hasCustomInventoryName() {
return duality.getStorage().hasCustomInventoryName();
return this.duality.getStorage().hasCustomInventoryName();
}
@Override
public int getInventoryStackLimit() {
return duality.getStorage().getInventoryStackLimit();
return this.duality.getStorage().getInventoryStackLimit();
}
@Override
public void markDirty() {
duality.markDirty();
this.duality.getStorage().markDirty();
}
@Override
public boolean isUseableByPlayer(EntityPlayer player) {
return duality.getStorage().isUseableByPlayer(player);
public boolean isUseableByPlayer(final EntityPlayer entityplayer) {
return this.duality.getStorage().isUseableByPlayer(entityplayer);
}
@Override
public void openInventory() {
duality.getStorage().openInventory();
this.duality.getStorage().openInventory();
}
@Override
public void closeInventory() {
duality.getStorage().closeInventory();
this.duality.getStorage().closeInventory();
}
@Override
public boolean isItemValidForSlot(int index, ItemStack stack) {
return duality.getStorage().isItemValidForSlot(index, stack);
public boolean isItemValidForSlot(final int i, final ItemStack itemstack) {
return this.duality.getStorage().isItemValidForSlot(i, itemstack);
}
@Override
public int[] getAccessibleSlotsFromSide(int side) {
return duality.getAccessibleSlotsFromSide(side);
public int[] getAccessibleSlotsFromSide(final int s) {
return this.duality.getAccessibleSlotsFromSide(s);
}
@Override
public boolean canInsertItem(int p_102007_1_, ItemStack itemStack, int p_102007_3_) {
public boolean canInsertItem(final int i, final ItemStack itemstack, final int j) {
return true;
}
@Override
public boolean canExtractItem(int p_102008_1_, ItemStack p_102008_2_, int p_102008_3_) {
public boolean canExtractItem(final int i, final ItemStack itemstack, final int j) {
return true;
}
@Override
public void onChangeInventory(final IInventory inv, final int slot, final InvOperation mc,
final ItemStack removedStack, final ItemStack newStack) {
this.duality.onChangeInventory(inv, slot, mc, removedStack, newStack);
}
@Override
public DualityInterface getInterfaceDuality() {
return this.duality;
}
@Override
public EnumSet<ForgeDirection> getTargets() {
return EnumSet.of(this.getSide());
}
@Override
public TileEntity getTileEntity() {
return super.getHost().getTile();
}
@Override
public IStorageMonitorable getMonitorable(final ForgeDirection side, final BaseActionSource src) {
return this.duality.getMonitorable(side, src, this);
}
@Override
public boolean pushPattern(final ICraftingPatternDetails patternDetails, final InventoryCrafting table) {
return this.duality.pushPattern(patternDetails, table);
}
@Override
public boolean isBusy() {
return this.duality.isBusy();
}
@Override
public void provideCrafting(final ICraftingProviderHelper craftingTracker) {
this.duality.provideCrafting(craftingTracker);
}
@Override
public ImmutableSet<ICraftingLink> getRequestedJobs() {
return this.duality.getRequestedJobs();
}
@Override
public IAEItemStack injectCraftedItems(final ICraftingLink link, final IAEItemStack items, final Actionable mode) {
return this.duality.injectCraftedItems(link, items, mode);
}
@Override
public void jobStateChange(final ICraftingLink link) {
this.duality.jobStateChange(link);
}
@Override
public int getPriority() {
return this.duality.getPriority();
}
@Override
public void setPriority(final int newValue) {
this.duality.setPriority(newValue);
}
@Override
public void onTunnelNetworkChange() {
this.duality.updateCraftingList();
updateSharingInventory();
}
@Override
public void onTunnelConfigChange() {
updateSharingInventory();
}
@Override
public IInventory getPatterns() {
if (isOutput()) {
PartFluidP2PInterface input = getInput();
if (input != null) {
return input.getPatterns();
}
return IInterfaceHost.super.getPatterns();
}
return IInterfaceHost.super.getPatterns();
}
@Override
public int rows() {
if (isOutput()) {
PartFluidP2PInterface input = getInput();
if (input != null) {
return input.rows();
}
return IInterfaceHost.super.rows();
}
return IInterfaceHost.super.rows();
}
@Override
public int rowSize() {
if (isOutput()) {
PartFluidP2PInterface input = getInput();
if (input != null) {
return input.rowSize();
}
return IInterfaceHost.super.rowSize();
}
return IInterfaceHost.super.rowSize();
}
@Override
public String getName() {
if (isOutput()) {
PartFluidP2PInterface input = getInput();
if (input != null) {
return input.getName();
}
return IInterfaceHost.super.getName();
}
return IInterfaceHost.super.getName();
}
@Override
public ItemStack getSelfRep() {
return this.getItemStack();
}
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
return dualityFluid.fill(from, resource, doFill);
@@ -420,138 +717,9 @@ public class PartFluidP2PInterface extends PartP2PTunnelStatic<PartFluidP2PInter
}
}
@Override
public DualityInterface getInterfaceDuality() {
return duality;
}
@Override
public EnumSet<ForgeDirection> getTargets() {
return EnumSet.of(this.getSide());
}
@Override
public TileEntity getTileEntity() {
return super.getHost().getTile();
}
@Override
public void provideCrafting(ICraftingProviderHelper craftingTracker) {
duality.provideCrafting(craftingTracker);
}
@Override
public boolean pushPattern(ICraftingPatternDetails patternDetails, InventoryCrafting table) {
return duality.pushPattern(patternDetails, table);
}
@Override
public boolean isBusy() {
return duality.isBusy();
}
@Override
public ImmutableSet<ICraftingLink> getRequestedJobs() {
return duality.getRequestedJobs();
}
@Override
public IAEItemStack injectCraftedItems(ICraftingLink link, IAEItemStack items, Actionable mode) {
return duality.injectCraftedItems(link, items, mode);
}
@Override
public void jobStateChange(ICraftingLink link) {
duality.jobStateChange(link);
}
@Override
public void readFromNBT(NBTTagCompound data) {
super.readFromNBT(data);
duality.readFromNBT(data);
}
@Override
public void writeToNBT(NBTTagCompound data) {
super.writeToNBT(data);
duality.writeToNBT(data);
}
@Override
public NBTTagCompound getMemoryCardData() {
final NBTTagCompound output = super.getMemoryCardData();
this.duality.getConfigManager().writeToNBT(output);
return output;
}
@Override
public void pasteMemoryCardData(PartP2PTunnel<?> newTunnel, NBTTagCompound data) throws GridAccessException {
this.duality.getConfigManager().readFromNBT(data);
super.pasteMemoryCardData(newTunnel, data);
}
@Override
public void addToWorld() {
super.addToWorld();
this.duality.initialize();
}
@Override
public void getDrops(List<ItemStack> drops, boolean wrenched) {
super.getDrops(drops, wrenched);
duality.addDrops(drops);
}
@Override
public boolean shouldDisplay() {
return IInterfaceHost.super.shouldDisplay();
}
@Override
public IInventory getPatterns() {
if (isOutput()) {
PartFluidP2PInterface input = getInput();
if (input != null) {
return input.getPatterns();
}
return IInterfaceHost.super.getPatterns();
}
return IInterfaceHost.super.getPatterns();
}
@Override
public int rows() {
if (isOutput()) {
PartFluidP2PInterface input = getInput();
if (input != null) {
return input.rows();
}
return IInterfaceHost.super.rows();
}
return IInterfaceHost.super.rows();
}
@Override
public int rowSize() {
if (isOutput()) {
PartFluidP2PInterface input = getInput();
if (input != null) {
return input.rowSize();
}
return IInterfaceHost.super.rowSize();
}
return IInterfaceHost.super.rowSize();
}
@Override
public String getName() {
if (isOutput()) {
PartFluidP2PInterface input = getInput();
if (input != null) {
return input.getName();
}
return IInterfaceHost.super.getName();
}
return IInterfaceHost.super.getName();
}
}
@@ -3,6 +3,7 @@ package com.glodblock.github.common.parts.base;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -10,14 +11,19 @@ import net.minecraft.nbt.NBTTagCompound;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.inventory.item.IItemPatternTerminal;
import appeng.api.networking.IGrid;
import appeng.api.storage.ITerminalPins;
import appeng.api.storage.data.IAEItemStack;
import appeng.items.contents.PinsHandler;
import appeng.items.contents.PinsHolder;
import appeng.tile.inventory.AppEngInternalInventory;
public abstract class FCFluidEncodeTerminal extends FCPart implements IItemPatternTerminal {
public abstract class FCFluidEncodeTerminal extends FCPart implements IItemPatternTerminal, ITerminalPins {
protected AppEngInternalInventory crafting;
protected AppEngInternalInventory output;
protected final AppEngInternalInventory pattern = new AppEngInternalInventory(this, 2);
private final PinsHolder pinsInv = new PinsHolder(this);
protected boolean craftingMode = true;
protected boolean substitute = false;
@@ -56,6 +62,7 @@ public abstract class FCFluidEncodeTerminal extends FCPart implements IItemPatte
this.pattern.readFromNBT(data, "pattern");
this.output.readFromNBT(data, "outputList");
this.crafting.readFromNBT(data, "craftingGrid");
pinsInv.readFromNBT(data, "pins");
}
@Override
@@ -72,6 +79,7 @@ public abstract class FCFluidEncodeTerminal extends FCPart implements IItemPatte
this.pattern.writeToNBT(data, "pattern");
this.output.writeToNBT(data, "outputList");
this.crafting.writeToNBT(data, "craftingGrid");
pinsInv.writeToNBT(data, "pins");
}
@Override
@@ -217,4 +225,14 @@ public abstract class FCFluidEncodeTerminal extends FCPart implements IItemPatte
public void setAutoFillPattern(boolean canFill) {
this.autoFillPattern = canFill;
}
@Override
public PinsHandler getPinsHandler(EntityPlayer player) {
return pinsInv.getHandler(player);
}
@Override
public IGrid getGrid() {
return getGridNode().getGrid();
}
}
@@ -366,21 +366,22 @@ public abstract class FCPart extends AEBasePart
rh.setBounds(2, 2, 14, 14, 14, 16);
rh.renderBlock(x, y, z, renderer);
final Tessellator tess = Tessellator.instance;
if (this.getLightLevel() > 0) {
final int l = 13;
Tessellator.instance.setBrightness(l << 20 | l << 4);
tess.setBrightness(l << 20 | l << 4);
}
renderer.uvRotateBottom = renderer.uvRotateEast = renderer.uvRotateNorth = renderer.uvRotateSouth = renderer.uvRotateTop = renderer.uvRotateWest = this
.getSpin();
Tessellator.instance.setColorOpaque_I(this.getColor().whiteVariant);
tess.setColorOpaque_I(this.getColor().whiteVariant);
rh.renderFace(x, y, z, this.getFrontBright().getIcon(), ForgeDirection.SOUTH, renderer);
Tessellator.instance.setColorOpaque_I(this.getColor().mediumVariant);
tess.setColorOpaque_I(this.getColor().mediumVariant);
rh.renderFace(x, y, z, this.getFrontDark().getIcon(), ForgeDirection.SOUTH, renderer);
Tessellator.instance.setColorOpaque_I(this.getColor().blackVariant);
tess.setColorOpaque_I(this.getColor().blackVariant);
rh.renderFace(x, y, z, this.getFrontColored().getIcon(), ForgeDirection.SOUTH, renderer);
renderer.uvRotateBottom = renderer.uvRotateEast = renderer.uvRotateNorth = renderer.uvRotateSouth = renderer.uvRotateTop = renderer.uvRotateWest = 0;
@@ -404,15 +405,15 @@ public abstract class FCPart extends AEBasePart
if (hasChan) {
final int l = 14;
Tessellator.instance.setBrightness(l << 20 | l << 4);
Tessellator.instance.setColorOpaque_I(this.getColor().blackVariant);
tess.setBrightness(l << 20 | l << 4);
tess.setColorOpaque_I(this.getColor().blackVariant);
} else if (hasPower) {
final int l = 9;
Tessellator.instance.setBrightness(l << 20 | l << 4);
Tessellator.instance.setColorOpaque_I(this.getColor().whiteVariant);
tess.setBrightness(l << 20 | l << 4);
tess.setColorOpaque_I(this.getColor().whiteVariant);
} else {
Tessellator.instance.setBrightness(0);
Tessellator.instance.setColorOpaque_I(0x000000);
tess.setBrightness(0);
tess.setColorOpaque_I(0x000000);
}
final IIcon sideStatusLightTexture = CableBusTextures.PartMonitorSidesStatusLights.getIcon();
@@ -148,7 +148,7 @@ public abstract class FCPartMonitor extends AbstractPartDisplay implements IPart
if (Platform.isWrench(player, eq, te.xCoord, te.yCoord, te.zCoord)) {
this.isLocked = !this.isLocked;
player.addChatMessage((this.isLocked ? PlayerMessages.isNowLocked : PlayerMessages.isNowUnlocked).get());
player.addChatMessage((this.isLocked ? PlayerMessages.isNowLocked : PlayerMessages.isNowUnlocked).toChat());
this.getHost().markForUpdate();
} else if (!this.isLocked) {
this.configuredFluid = AEFluidStack.create(Util.FluidUtil.getFluidFromContainer(eq));
@@ -399,21 +399,22 @@ public abstract class FCPartMonitor extends AbstractPartDisplay implements IPart
rh.setBounds(2, 2, 14, 14, 14, 16);
rh.renderBlock(x, y, z, renderer);
final Tessellator tess = Tessellator.instance;
if (this.getLightLevel() > 0) {
final int l = 13;
Tessellator.instance.setBrightness(l << 20 | l << 4);
tess.setBrightness(l << 20 | l << 4);
}
renderer.uvRotateBottom = renderer.uvRotateEast = renderer.uvRotateNorth = renderer.uvRotateSouth = renderer.uvRotateTop = renderer.uvRotateWest = this
.getSpin();
Tessellator.instance.setColorOpaque_I(this.getColor().whiteVariant);
tess.setColorOpaque_I(this.getColor().whiteVariant);
rh.renderFace(x, y, z, this.getFrontBright().getIcon(), ForgeDirection.SOUTH, renderer);
Tessellator.instance.setColorOpaque_I(this.getColor().mediumVariant);
tess.setColorOpaque_I(this.getColor().mediumVariant);
rh.renderFace(x, y, z, this.getFrontDark().getIcon(), ForgeDirection.SOUTH, renderer);
Tessellator.instance.setColorOpaque_I(this.getColor().blackVariant);
tess.setColorOpaque_I(this.getColor().blackVariant);
rh.renderFace(x, y, z, this.getFrontColored().getIcon(), ForgeDirection.SOUTH, renderer);
renderer.uvRotateBottom = renderer.uvRotateEast = renderer.uvRotateNorth = renderer.uvRotateSouth = renderer.uvRotateTop = renderer.uvRotateWest = 0;
@@ -437,15 +438,15 @@ public abstract class FCPartMonitor extends AbstractPartDisplay implements IPart
if (hasChan) {
final int l = 14;
Tessellator.instance.setBrightness(l << 20 | l << 4);
Tessellator.instance.setColorOpaque_I(this.getColor().blackVariant);
tess.setBrightness(l << 20 | l << 4);
tess.setColorOpaque_I(this.getColor().blackVariant);
} else if (hasPower) {
final int l = 9;
Tessellator.instance.setBrightness(l << 20 | l << 4);
Tessellator.instance.setColorOpaque_I(this.getColor().whiteVariant);
tess.setBrightness(l << 20 | l << 4);
tess.setColorOpaque_I(this.getColor().whiteVariant);
} else {
Tessellator.instance.setBrightness(0);
Tessellator.instance.setColorOpaque_I(0x000000);
tess.setBrightness(0);
tess.setColorOpaque_I(0x000000);
}
final IIcon sideStatusLightTexture = CableBusTextures.PartMonitorSidesStatusLights.getIcon();
@@ -200,7 +200,7 @@ public class FluidCellInventory implements IFluidCellInventory {
@Override
public long getRemainingFluidTypes() {
final long basedOnStorage = this.getFreeBytes() / this.getBytesPerType();
final long basedOnStorage = this.getFreeBytes() / Math.max(1, this.getBytesPerType());
final long baseOnTotal = this.getTotalFluidTypes() - this.getStoredFluidTypes();
return Math.min(basedOnStorage, baseOnTotal);
}
@@ -6,6 +6,7 @@ import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.util.Ae2Reflect;
import com.glodblock.github.util.Util;
@@ -42,6 +43,12 @@ public class FluidCellInventoryHandler extends MEInventoryHandler<IAEFluidStack>
AEFluidStack stack = AEFluidStack.create(fluid);
stack.setStackSize(1);
priorityList.add(stack);
// convert partition on cells in network
if (!(is.getItem() instanceof ItemFluidPacket)) {
config.setInventorySlotContents(x, ItemFluidPacket.newDisplayStack(fluid));
config.markDirty();
}
}
}
if (!priorityList.isEmpty()) {
@@ -277,11 +277,20 @@ public class TileFluidAutoFiller extends AENetworkInvTile
@Override
public TickingRequest getTickingRequest(IGridNode node) {
return new TickingRequest(1, 5, this.returnStack == null, true);
return new TickingRequest(1, 5, false, true);
}
boolean initialized = false;
@Override
public TickRateModulation tickingRequest(IGridNode node, int TicksSinceLastCall) {
if (!initialized) { // run postEvent on AE network is ready
initialized = true;
postEvent();
}
if (this.returnStack == null) return TickRateModulation.SLEEP;
if (this.getStorageGrid() == null) {
return TickRateModulation.SLOWER;
}
@@ -1,23 +1,30 @@
package com.glodblock.github.common.tile;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Objects;
import java.util.concurrent.Future;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.glodblock.github.api.registries.ILevelViewable;
import com.glodblock.github.api.registries.LevelItemInfo;
import com.glodblock.github.api.registries.LevelState;
import com.glodblock.github.common.Config;
import com.glodblock.github.common.item.ItemFluidDrop;
import com.glodblock.github.crossmod.thaumcraft.ThaumicEnergisticsCrafting;
import com.glodblock.github.inventory.AeItemStackHandler;
import com.glodblock.github.inventory.AeStackInventory;
import com.glodblock.github.inventory.AeStackInventoryImpl;
import com.glodblock.github.util.ModAndClassUtil;
import com.google.common.collect.ImmutableSet;
@@ -42,19 +49,16 @@ import appeng.api.networking.security.MachineSource;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.core.AELog;
import appeng.helpers.NonNullArrayIterator;
import appeng.me.GridAccessException;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkTile;
import appeng.tile.inventory.IAEAppEngInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import io.netty.buffer.ByteBuf;
@@ -62,10 +66,19 @@ public class TileLevelMaintainer extends AENetworkTile
implements IAEAppEngInventory, IGridTickable, ICraftingRequester, IPowerChannelState, ILevelViewable {
public static final int REQ_COUNT = 5;
public final InventoryRequest requests = new InventoryRequest(this);
public static final String NBT_REQUESTS = "Requests";
public static final String NBT_STACK = "stack";
public static final String NBT_QUANTITY = "quantity";
public static final String NBT_BATCH = "batch";
public static final String NBT_ENABLE = "enable";
public static final String NBT_STATE = "state";
public static final String NBT_LINK = "link";
public final RequestInfo[] requests = new RequestInfo[REQ_COUNT];
private final LevelMaintainerInventory inventory = new LevelMaintainerInventory(requests, this);
private int firstRequest = 0;
private final BaseActionSource source;
private final IInventory inv = new AeItemStackHandler(requests.requestStacks);
private final IInventory inv = new AeItemStackHandler(inventory);
private boolean isPowered = false;
public TileLevelMaintainer() {
@@ -75,17 +88,23 @@ public class TileLevelMaintainer extends AENetworkTile
}
public AeStackInventory<IAEItemStack> getRequestSlots() {
return requests.requestStacks;
return inventory;
}
@Override
public ImmutableSet<ICraftingLink> getRequestedJobs() {
return ImmutableSet.copyOf(new NonNullArrayIterator<>(requests.links));
return ImmutableSet.copyOf(
Arrays.stream(this.requests).filter(Objects::nonNull).map(info -> info.link).filter(Objects::nonNull)
.iterator());
}
@Override
public IAEItemStack injectCraftedItems(ICraftingLink link, IAEItemStack items, Actionable mode) {
int idx = requests.getIdxByLink(link);
int idx = this.getRequestIndexByLink(link);
if (idx == -1) {
AELog.warn("Invalid crafting link: " + link);
return items;
}
try {
if (getProxy().isActive()) {
final IEnergyGrid energy = getProxy().getEnergy();
@@ -97,7 +116,7 @@ public class TileLevelMaintainer extends AENetworkTile
.injectItems(ItemFluidDrop.getAeFluidStack(items), mode, source);
if (notInjectedItems != null) {
items.setStackSize(notInjectedItems.getStackSize());
requests.updateState(idx, State.Export);
this.updateState(idx, LevelState.Export);
return items;
} else {
@@ -117,10 +136,12 @@ public class TileLevelMaintainer extends AENetworkTile
@Override
public void jobStateChange(ICraftingLink link) {
for (int x = 0; x < REQ_COUNT; x++) {
if (requests.getLink(x) == link) {
requests.updateLink(x, link);
return;
for (int i = 0; i < REQ_COUNT; i++) {
if (requests[i] != null && link != null) {
ICraftingLink prevLink = requests[i].link;
if (prevLink != null && prevLink.getCraftingID().equals(link.getCraftingID())) {
this.updateLink(i, null);
}
}
}
}
@@ -164,92 +185,107 @@ public class TileLevelMaintainer extends AENetworkTile
for (int j = 0; j < REQ_COUNT; ++j) {
int i = (firstRequest + j) % REQ_COUNT;
if (requests[i] == null) continue;
long quantity = requests.getQuantity(i);
long batchSize = requests.getBatchSize(i);
boolean isEnable = requests.isEnable(i);
if (!isEnable || batchSize == 0) requests.updateState(i, State.None);
if (batchSize > 0) {
IAEItemStack craftItem = requests.getCraftItem(i);
final long quantity = requests[i].quantity;
final long batchSize = requests[i].batchSize;
final boolean isEnable = requests[i].enable;
if (ModAndClassUtil.ThE) {
if (craftItem != null && ThaumicEnergisticsCrafting.isAspectStack(craftItem.getItemStack())) {
craftItem = ThaumicEnergisticsCrafting.convertAspectStack(craftItem);
}
}
if (!isEnable || quantity == 0 || batchSize == 0) {
this.updateState(i, LevelState.None);
continue;
}
IAEItemStack aeItem = inv.findPrecise(craftItem);
IAEItemStack craftItem = requests[i].itemStack.copy();
craftItem.setStackSize(batchSize);
long stackSize = aeItem == null ? 0 : aeItem.getStackSize();
if (ModAndClassUtil.ThE) {
if (aeItem != null && ThaumicEnergisticsCrafting.isAspectStack(aeItem.getItemStack())) {
stackSize = ThaumicEnergisticsCrafting.getEssentiaAmount(aeItem, grid);
}
}
boolean isDone = requests.isDone(i);
boolean isCraftable = aeItem != null && aeItem.isCraftable();
boolean shouldCraft = isCraftable && stackSize < quantity;
if (isDone) requests.updateState(i, State.Idle);
if (!isCraftable) requests.updateState(i, State.Error);
if (allBusy || !isDone || !shouldCraft) {
continue;
}
if (craftingGrid.canEmitFor(craftItem)) {
continue;
}
if (craftingGrid.isRequesting(craftItem)) {
continue;
}
// do crafting
Future<ICraftingJob> jobTask = requests.getJob(i);
if (jobTask == null) {
if (itemToBegin == null) {
itemToBegin = craftItem;
itemToBeginIdx = i;
}
} else if (jobTask.isDone()) {
requests.updateState(i, State.Craft);
try {
ICraftingJob job = jobTask.get();
if (job != null) {
if (jobToSubmit == null) {
jobToSubmit = job;
jobToSubmitIdx = i;
}
} else {
requests.updateState(i, State.Error);
}
} catch (Exception ignored) {
requests.updateState(i, State.Error);
}
if (ModAndClassUtil.ThE) {
if (ThaumicEnergisticsCrafting.isAspectStack(craftItem.getItemStack())) {
craftItem = ThaumicEnergisticsCrafting.convertAspectStack(craftItem);
}
}
IAEItemStack aeItem = inv.findPrecise(craftItem);
long stackSize = aeItem == null ? 0 : aeItem.getStackSize();
if (ModAndClassUtil.ThE) {
if (aeItem != null && ThaumicEnergisticsCrafting.isAspectStack(aeItem.getItemStack())) {
stackSize = ThaumicEnergisticsCrafting.getEssentiaAmount(aeItem, grid);
}
}
boolean isDone = this.isDone(i);
boolean isCraftable = aeItem != null && aeItem.isCraftable();
boolean shouldCraft = isCraftable && stackSize < quantity;
if (isDone) {
if (this.requests[i].state != LevelState.Idle) {
this.updateState(i, LevelState.Idle);
}
if (this.requests[i].link != null) {
this.updateLink(i, null);
}
if (!isCraftable) {
updateState(i, LevelState.NotFound);
}
}
if (allBusy || !isDone || !shouldCraft) {
continue;
}
if (craftingGrid.canEmitFor(craftItem)) {
continue;
}
if (craftingGrid.isRequesting(craftItem)) {
continue;
}
// do crafting
Future<ICraftingJob> jobTask = requests[i].job;
if (jobTask == null) {
if (itemToBegin == null) {
itemToBegin = craftItem;
itemToBeginIdx = i;
}
} else if (jobTask.isDone()) {
this.updateState(i, LevelState.Craft);
try {
ICraftingJob job = jobTask.get();
if (job != null) {
if (jobToSubmit == null) {
jobToSubmit = job;
jobToSubmitIdx = i;
}
} else {
this.updateState(i, LevelState.Error);
}
} catch (Exception ignored) {
this.updateState(i, LevelState.Error);
}
}
}
if (jobToSubmit != null) {
// Finished calculating a request, try to submit it.
ICraftingLink link = craftingGrid.submitJob(jobToSubmit, this, null, false, source);
requests.updateJob(jobToSubmitIdx, null);
requests[jobToSubmitIdx].job = null;
if (link != null) {
requests.updateState(jobToSubmitIdx, State.Craft);
requests.updateLink(jobToSubmitIdx, link);
this.updateState(jobToSubmitIdx, LevelState.Craft);
this.updateLink(jobToSubmitIdx, link);
} else {
requests.updateState(jobToSubmitIdx, State.Error);
this.updateState(jobToSubmitIdx, LevelState.CantCraft);
}
} else if (itemToBegin != null) {
// No jobs to submit, start calculating some item.
requests.updateJob(
itemToBeginIdx,
craftingGrid.beginCraftingJob(getWorldObj(), grid, source, itemToBegin, null));
requests.updateState(itemToBeginIdx, State.Craft);
requests[itemToBeginIdx].job = craftingGrid
.beginCraftingJob(getWorldObj(), grid, source, itemToBegin, null);
this.updateState(itemToBeginIdx, LevelState.Craft);
// Try the next item next time.
firstRequest = (firstRequest + 1) % REQ_COUNT;
@@ -284,9 +320,6 @@ public class TileLevelMaintainer extends AENetworkTile
return getProxy().isActive();
}
@Override
public void gridChanged() {}
@Override
public boolean isPowered() {
return isPowered;
@@ -297,120 +330,208 @@ public class TileLevelMaintainer extends AENetworkTile
return isPowered;
}
public InventoryRequest getRequestInventory() {
return requests;
}
public IInventory getInventory() {
return inv;
}
public IInventory getInventoryByName(String name) {
if (name == "config") return new AeItemStackHandler(requests.requestStacks);
if (Objects.equals(name, "config")) return new AeItemStackHandler(this.inventory);
return null;
}
@Override
public LevelItemInfo[] getLevelItemInfoList() {
return Arrays.stream(this.requests).map(request -> {
if (request == null) return null;
return new LevelItemInfo(
request.itemStack.getItemStack(),
request.getQuantity(),
request.getBatchSize(),
request.getState());
}).toArray(LevelItemInfo[]::new);
}
public void updateQuantity(int idx, long size) {
requests.updateQuantity(idx, size);
if (requests[idx] == null) return;
requests[idx].quantity = size > 0 ? size : 0;
this.checkState(idx);
this.saveChanges();
}
public void updateBatchSize(int idx, long size) {
requests.updateBatchSize(idx, size);
if (requests[idx] == null) return;
requests[idx].batchSize = size > 0 ? size : 0;
this.checkState(idx);
this.saveChanges();
}
public void updateStatus(int idx, boolean enable) {
requests.updateStatus(idx, enable);
if (requests[idx] == null) return;
requests[idx].enable = enable;
this.checkState(idx);
this.saveChanges();
}
/**
* @deprecated
*/
@Deprecated
private void readLinkFromNBT__old(NBTTagCompound data) {
try {
for (int i = 0; i < REQ_COUNT; i++) {
final NBTTagCompound link = data.getCompoundTag("links-" + i);
if (link != null && link.hasNoTags()) {
requests.updateLink(i, null);
} else {
requests.updateLink(i, AEApi.instance().storage().loadCraftingLink(link, this));
if (!requests.isDone(i)) requests.updateState(i, State.Craft);
private void updateState(int idx, @NotNull LevelState state) {
if (requests[idx] == null) return;
requests[idx].state = state;
this.saveChanges();
}
public void updateStack(int idx, @Nullable ItemStack stack) {
if (stack == null) {
requests[idx] = null;
} else {
stack = this.removeRecursion(stack);
requests[idx] = new RequestInfo(stack, this);
}
this.saveChanges();
}
private void updateLink(int idx, @Nullable ICraftingLink link) {
if (requests[idx] == null) return;
requests[idx].link = link;
this.saveChanges();
}
private void checkState(int idx) {
if (!requests[idx].enable || requests[idx].quantity == 0 || requests[idx].batchSize == 0) {
this.updateState(idx, LevelState.None);
} else if (!this.isDone(idx)) {
this.updateState(idx, LevelState.Craft);
} else {
this.updateState(idx, LevelState.Idle);
}
}
public boolean isDone(int i) {
if (requests[i] == null) {
return true;
}
ICraftingLink link = requests[i].link;
return link == null || link.isDone() || link.isCanceled();
}
private int getRequestIndexByLink(ICraftingLink targetLink) {
for (int i = 0; i < REQ_COUNT; i++) {
if (requests[i] != null && targetLink != null) {
ICraftingLink link = requests[i].link;
if (link != null && link.getCraftingID().equals(targetLink.getCraftingID())) {
return i;
}
}
} catch (Exception ignore) {}
}
return -1;
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBTEvent(NBTTagCompound data) {
requests.requestStacks.writeToNbt(data, TLMTags.RequestStacks.tagName);
NBTTagList tagList = new NBTTagList();
for (int i = 0; i < REQ_COUNT; i++) {
if (this.requests[i] != null) {
tagList.appendTag(this.requests[i].writeToNBT());
} else {
tagList.appendTag(new NBTTagCompound());
}
}
data.setTag(NBT_REQUESTS, tagList);
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBTEvent(NBTTagCompound data) {
if (data.hasKey(TLMTags.RequestStacks.tagName)) {
requests.requestStacks.readFromNbt(data, TLMTags.RequestStacks.tagName);
if (Platform.isServer()) {
for (int i = 0; i < REQ_COUNT; i++) {
if (requests.requestStacks.getStack(i) != null) {
ItemStack storageStack = requests.requestStacks.getStack(i).getItemStack();
ItemStack itemStack = loadItemStackFromTag(storageStack);
ItemStack craftStack = removeRecursion(storageStack);
if (!ItemStack.areItemStacksEqual(itemStack, craftStack)) {
requests.updateStack(i, craftStack);
AELog.info(
"[TileLevelMaintainer] Replace craft stack from: " + itemStack.toString()
+ ":"
+ (itemStack.hasTagCompound() ? itemStack.getTagCompound() : "{no tags}")
+ "; with: "
+ craftStack
+ ":"
+ (craftStack.hasTagCompound() ? craftStack.getTagCompound()
: "{no tags}"));
}
if (data.hasKey(NBT_REQUESTS)) {
NBTTagList tagList = data.getTagList(NBT_REQUESTS, Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < tagList.tagCount(); i++) {
NBTTagCompound tag = tagList.getCompoundTagAt(i);
if (tag == null || !tag.hasKey(NBT_STACK)) {
this.requests[i] = null;
} else if (this.requests[i] == null) {
try {
this.requests[i] = new RequestInfo(tag, this);
} catch (Exception ignored) {
this.requests[i] = null;
}
} else {
this.requests[i].loadFromNBT(tag);
}
}
} else if (data.hasKey("RequestStacks")) {
// Migration from old NBT
NBTTagList stacksTag = data.getCompoundTag("RequestStacks")
.getTagList("Contents", Constants.NBT.TAG_COMPOUND);
IAEItemStack[] stacks = new IAEItemStack[REQ_COUNT];
for (int i = 0; i < REQ_COUNT; i++) {
NBTTagCompound stackTag = stacksTag.getCompoundTagAt(i);
if (stackTag == null) continue;
stacks[i] = AEItemStack.loadItemStackFromNBT(stackTag);
if (stacks[i] == null) continue;
ItemStack itemstack = stacks[i].getItemStack();
if (!itemstack.hasTagCompound()) continue;
NBTTagCompound itemTag = itemstack.getTagCompound();
ItemStack craftStack = ItemStack.loadItemStackFromNBT(itemTag.getCompoundTag("Stack"));
craftStack = removeRecursion(craftStack);
if (craftStack == null) continue;
requests[i] = new RequestInfo(craftStack, this);
if (itemTag.hasKey("Enable")) {
requests[i].enable = itemTag.getBoolean("Enable");
}
if (itemTag.hasKey("Quantity")) {
requests[i].quantity = itemTag.getLong("Quantity");
}
if (itemTag.hasKey("Batch")) {
requests[i].batchSize = itemTag.getLong("Batch");
}
}
} else {
// Migration from old data storage
// Migration from old old data storage
long[] batches = new long[REQ_COUNT];
long[] quantyties = new long[REQ_COUNT];
requests.requestStacks.readFromNbt(data, "Batch");
ItemStack[] stacks = new ItemStack[REQ_COUNT];
NBTTagList batchTag = data.getCompoundTag("Batch").getTagList("Contents", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < REQ_COUNT; i++) {
IAEItemStack batchStack = requests.requestStacks.getStack(i);
batches[i] = batchStack != null ? batchStack.getStackSize() : 0;
NBTTagCompound stackTag = batchTag.getCompoundTagAt(i);
IAEItemStack stack = AEItemStack.loadItemStackFromNBT(stackTag);
batches[i] = stack != null ? stack.getStackSize() : 0;
}
requests.requestStacks.readFromNbt(data, "Count");
NBTTagList quantityTag = data.getCompoundTag("Count").getTagList("Contents", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < REQ_COUNT; i++) {
IAEItemStack quantityStack = requests.requestStacks.getStack(i);
quantyties[i] = quantityStack != null ? quantityStack.getStackSize() : 0;
NBTTagCompound stackTag = quantityTag.getCompoundTagAt(i);
IAEItemStack stack = AEItemStack.loadItemStackFromNBT(stackTag);
quantyties[i] = stack != null ? stack.getStackSize() : 0;
}
requests.requestStacks.readFromNbt(data, "Inventory");
NBTTagList inventoryTag = data.getCompoundTag("Count").getTagList("Contents", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < REQ_COUNT; i++) {
IAEItemStack requestsStack = requests.requestStacks.getStack(i);
if (requestsStack != null) {
requests.updateStack(i, requestsStack.getItemStack());
requests.updateBatchSize(i, batches[i]);
requests.updateQuantity(i, quantyties[i]);
}
NBTTagCompound stackTag = inventoryTag.getCompoundTagAt(i);
IAEItemStack stack = AEItemStack.loadItemStackFromNBT(stackTag);
stacks[i] = stack != null ? stack.getItemStack() : null;
}
for (int i = 0; i < REQ_COUNT; i++) {
if (stacks[i] == null) continue;
this.requests[i] = new RequestInfo(stacks[i], this);
this.requests[i].batchSize = batches[i];
this.requests[i].quantity = quantyties[i];
}
readLinkFromNBT__old(data);
}
}
// Remove old format NBT data from ItemStack
private ItemStack removeRecursion(ItemStack itemStack) {
if (itemStack != null && itemStack.hasTagCompound()
&& itemStack.getTagCompound().hasKey(TLMTags.Stack.tagName)) {
return removeRecursion(loadItemStackFromTag(itemStack));
if (itemStack == null || !itemStack.hasTagCompound()) return itemStack;
NBTTagCompound tag = itemStack.getTagCompound();
if (tag.hasKey("Stack") && tag.hasKey("Quantity")) {
return removeRecursion(ItemStack.loadItemStackFromNBT(itemStack.getTagCompound().getCompoundTag("Stack")));
}
return itemStack;
}
@Nullable
private static ItemStack loadItemStackFromTag(ItemStack itemStack) {
return ItemStack.loadItemStackFromNBT(itemStack.getTagCompound().getCompoundTag(TLMTags.Stack.tagName));
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream(final ByteBuf data) {
final boolean oldPower = isPowered;
@@ -449,7 +570,7 @@ public class TileLevelMaintainer extends AENetworkTile
}
@Override
public TileEntity getTile() {
public @NotNull TileEntity getTile() {
return this;
}
@@ -463,209 +584,140 @@ public class TileLevelMaintainer extends AENetworkTile
return REQ_COUNT;
}
@Override
public ItemStack getSelfItemStack() {
return getItemFromTile(this);
}
public static class RequestInfo {
public enum State {
None,
Idle,
Craft,
Export,
Error
}
private final TileLevelMaintainer tile;
private @NotNull IAEItemStack itemStack;
private long quantity;
private long batchSize;
private boolean enable;
private LevelState state;
@Nullable
private Future<ICraftingJob> job;
@Nullable
private ICraftingLink link;
public enum TLMTags {
RequestStacks("RequestStacks"),
Enable("Enable"),
Quantity("Quantity"),
Batch("Batch"),
Link("Link"),
State("State"),
Index("Index"),
Stack("Stack");
public final String tagName;
TLMTags(String tagName) {
this.tagName = tagName;
}
}
public static final class InventoryRequest {
private final AeStackInventoryImpl<IAEItemStack> requestStacks;
private final Future<ICraftingJob>[] jobs;
private final ICraftingLink[] links;
private final State[] state = new State[REQ_COUNT];
@SuppressWarnings("unchecked")
public InventoryRequest(TileLevelMaintainer tile) {
requestStacks = new AeStackInventoryImpl<>(StorageChannel.ITEMS, REQ_COUNT, tile);
jobs = new Future[REQ_COUNT];
links = new ICraftingLink[REQ_COUNT];
public RequestInfo(@NotNull ItemStack stack, TileLevelMaintainer tile) {
this.tile = tile;
itemStack = AEItemStack.create(stack);
quantity = 0;
batchSize = 0;
enable = false;
state = LevelState.None;
link = null;
job = null;
}
public State getState(int idx) {
IAEItemStack ias = requestStacks.getStack(idx);
if (ias == null) {
return State.None;
} else {
return state[idx] == null ? State.Idle : state[idx];
public RequestInfo(NBTTagCompound tag, TileLevelMaintainer tile) throws IllegalArgumentException {
this.tile = tile;
itemStack = AEItemStack.loadItemStackFromNBT(tag.getCompoundTag(NBT_STACK));
if (itemStack == null) {
throw new IllegalArgumentException("ItemStack cannot be null!");
}
}
public int getIdxByLink(ICraftingLink link) {
for (int i = 0; i < REQ_COUNT; i++) {
if (links[i] == link) {
return i;
quantity = tag.getLong(NBT_QUANTITY);
batchSize = tag.getLong(NBT_BATCH);
enable = tag.getBoolean(NBT_ENABLE);
state = LevelState.values()[tag.getInteger(NBT_STATE)];
if (tag.hasKey(NBT_LINK)) {
try {
this.link = AEApi.instance().storage().loadCraftingLink(tag.getCompoundTag(NBT_LINK), this.tile);
} catch (Exception ignored) {
this.link = null;
}
}
return 0;
job = null;
}
public boolean isEnable(int idx) {
IAEItemStack ias = requestStacks.getStack(idx);
if (ias == null) {
return true;
public void loadFromNBT(NBTTagCompound tag) {
itemStack = AEItemStack.loadItemStackFromNBT(tag.getCompoundTag(NBT_STACK));
quantity = tag.getLong(NBT_QUANTITY);
batchSize = tag.getLong(NBT_BATCH);
enable = tag.getBoolean(NBT_ENABLE);
state = LevelState.values()[tag.getInteger(NBT_STATE)];
if (tag.hasKey(NBT_LINK)) {
try {
this.link = AEApi.instance().storage().loadCraftingLink(tag.getCompoundTag(NBT_LINK), this.tile);
} catch (Exception ignored) {
this.link = null;
}
}
ItemStack is = ias.getItemStack();
return is.hasTagCompound() ? is.getTagCompound().getBoolean(TLMTags.Enable.tagName) : true;
}
public boolean isDone(int index) {
if (links[index] == null) {
return true;
public NBTTagCompound writeToNBT() {
NBTTagCompound tag = new NBTTagCompound();
NBTTagCompound stackTag = new NBTTagCompound();
itemStack.writeToNBT(stackTag);
tag.setTag(NBT_STACK, stackTag);
tag.setLong(NBT_QUANTITY, quantity);
tag.setLong(NBT_BATCH, batchSize);
tag.setBoolean(NBT_ENABLE, enable);
tag.setInteger(NBT_STATE, state.ordinal());
if (this.link != null) {
NBTTagCompound linkTag = new NBTTagCompound();
this.link.writeToNBT(linkTag);
tag.setTag(NBT_LINK, linkTag);
}
return links[index].isDone() || links[index].isCanceled();
return tag;
}
public Future<ICraftingJob> getJob(int idx) {
return jobs[idx];
public IAEItemStack getAEItemStack() {
return this.itemStack;
}
public ICraftingLink getLink(int idx) {
return links[idx];
public long getQuantity() {
return quantity;
}
public void updateJob(int idx, Future<ICraftingJob> job) {
jobs[idx] = job;
public long getBatchSize() {
return batchSize;
}
private void updateField(int idx, UnaryOperator<NBTTagCompound> updater) {
IAEItemStack ias = requestStacks.getStack(idx);
if (ias == null) return;
ItemStack itemStack = ias.getItemStack();
NBTTagCompound data = itemStack.hasTagCompound() ? itemStack.getTagCompound() : new NBTTagCompound();
data.setInteger(TLMTags.Index.tagName, idx);
itemStack.setTagCompound(updater.apply(data));
IAEItemStack newRequestStack = AEItemStack.create(itemStack);
newRequestStack.setStackSize(ias.getStackSize());
requestStacks.setStack(idx, newRequestStack);
public boolean isEnable() {
return enable;
}
public void updateLink(int idx, ICraftingLink link) {
links[idx] = link;
public LevelState getState() {
return state;
}
}
updateField(idx, data -> {
NBTTagCompound linkData = new NBTTagCompound();
if (link != null) link.writeToNBT(linkData);
data.setTag(TLMTags.Link.tagName, linkData);
private static class LevelMaintainerInventory implements AeStackInventory<IAEItemStack> {
return data;
});
private final RequestInfo[] requests;
private final TileLevelMaintainer tile;
private LevelMaintainerInventory(RequestInfo[] requests, TileLevelMaintainer tile) {
this.requests = requests;
this.tile = tile;
}
public void updateState(int idx, State nextState) {
state[idx] = nextState;
updateField(idx, data -> {
data.setInteger(TLMTags.State.tagName, nextState.ordinal());
return data;
});
@Override
public @NotNull Iterator<IAEItemStack> iterator() {
return Arrays.stream(requests).map(info -> info != null ? info.itemStack : null).iterator();
}
public void updateStatus(int idx, boolean enable) {
updateField(idx, data -> {
State nextState = enable ? State.Idle : State.None;
data.setBoolean(TLMTags.Enable.tagName, enable);
data.setInteger(TLMTags.State.tagName, nextState.ordinal());
return data;
});
@Override
public int getSlotCount() {
return requests.length;
}
public void updateQuantity(int idx, long quantity) {
updateField(idx, data -> {
data.setLong(TLMTags.Quantity.tagName, quantity);
return data;
});
@Override
public @Nullable IAEItemStack getStack(int slot) {
return requests[slot] != null ? requests[slot].itemStack : null;
}
public void updateBatchSize(int idx, long batch) {
updateField(idx, data -> {
data.setLong(TLMTags.Batch.tagName, batch);
data.setBoolean(TLMTags.Enable.tagName, true);
return data;
});
@Override
public void setStack(int slot, @Nullable IAEItemStack stack) {
if (stack == null) {
this.tile.updateStack(slot, null);
} else {
this.tile.updateStack(slot, stack.getItemStack());
}
}
public void updateStack(int idx, ItemStack itemStack) {
updateField(idx, data -> {
NBTTagCompound stackData = new NBTTagCompound();
if (itemStack != null) itemStack.writeToNBT(stackData);
data.setTag(TLMTags.Stack.tagName, stackData);
return data;
});
}
public IAEItemStack getAEItemStack(int idx) {
return requestStacks.getStack(idx);
}
public ItemStack getItemStack(int idx) {
return requestStacks.getStack(idx).getItemStack();
}
public long getQuantity(int idx) {
if (!isEnable(idx)) return 0;
IAEItemStack ias = requestStacks.getStack(idx);
if (ias == null) return 0;
ItemStack itemStack = ias.getItemStack();
if (!itemStack.hasTagCompound()) return 0;
return itemStack.getTagCompound().getLong(TLMTags.Quantity.tagName);
}
public long getBatchSize(int idx) {
if (!isEnable(idx)) return 0;
IAEItemStack ias = requestStacks.getStack(idx);
if (ias == null) return 0;
ItemStack itemStack = ias.getItemStack();
if (!itemStack.hasTagCompound()) return 0;
return itemStack.getTagCompound().getLong(TLMTags.Batch.tagName);
}
public IAEItemStack getCraftItem(int idx) {
IAEItemStack is = requestStacks.getStack(idx);
if (is == null) return null;
if (is.getItemStack() == null) return null;
ItemStack qis = loadItemStackFromTag(is.getItemStack());
if (qis == null) return null;
IAEItemStack qais = AEItemStack.create(qis);
qais.setStackSize(getBatchSize(idx));
return qais;
@Override
public Stream<IAEItemStack> stream() {
return Arrays.stream(requests).map(info -> info != null ? info.itemStack : null);
}
}
}
@@ -0,0 +1,463 @@
package com.glodblock.github.common.tile;
import java.util.List;
import java.util.stream.IntStream;
import javax.annotation.Nonnull;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import com.glodblock.github.common.item.FCBaseItemCell;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.inventory.AEFluidInventory;
import com.glodblock.github.inventory.IAEFluidInventory;
import com.glodblock.github.inventory.IAEFluidTank;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.implementations.IPowerChannelState;
import appeng.api.networking.GridFlags;
import appeng.api.networking.IGridNode;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.MachineSource;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.core.AELog;
import appeng.items.storage.ItemBasicStorageCell;
import appeng.me.GridAccessException;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkInvTile;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.item.AEFluidStack;
import appeng.util.item.AEItemStack;
import io.netty.buffer.ByteBuf;
public class TileSuperStockReplenisher extends AENetworkInvTile
implements IAEFluidInventory, IFluidHandler, IPowerChannelState, IGridTickable {
private final AppEngInternalInventory cell = new AppEngInternalInventory(this, 1);
private final AppEngInternalInventory invItems = new AppEngInternalInventory(this, 63);
private final AEFluidInventory invFluids = new AEFluidInventory(this, 9, Integer.MAX_VALUE);
private final AppEngInternalAEInventory configFluids = new AppEngInternalAEInventory(this, 9);
private final AppEngInternalAEInventory configItems = new AppEngInternalAEInventory(this, 63);
private final BaseActionSource source;
private boolean isPowered;
private long totalBytes;
private long storedFluidCount;
private long storedItemCount;
public TileSuperStockReplenisher() {
getProxy().setIdlePowerUsage(4D);
getProxy().setFlags(GridFlags.REQUIRE_CHANNEL);
this.source = new MachineSource(this);
invItems.setMaxStackSize(Integer.MAX_VALUE);
}
private TickRateModulation doWork() {
for (int i = 0; i < 9; i++) {
IAEFluidStack invFluid = invFluids.getFluidInSlot(i);
IAEItemStack configFluid = configFluids.getAEStackInSlot(i);
if (configFluid != null) {
IAEFluidStack fs = AEFluidStack.create(ItemFluidPacket.getFluidStack(configFluid));
if (invFluid == null) requestFluid(fs, i);
else if (invFluid.equals(fs)) {
long invSize = invFluid.getStackSize();
long confSize = fs.getStackSize();
if (invSize < confSize / 2f) {
fs.setStackSize(confSize - invSize);
requestFluid(fs, i);
} else if (invSize > confSize) {
returnFluid(i, invSize - confSize);
}
} else {
returnFluid(i, Long.MAX_VALUE);
}
} else if (invFluid != null) {
returnFluid(i, Long.MAX_VALUE);
}
}
for (int i = 0; i < 63; i++) {
ItemStack invItem = invItems.getStackInSlot(i);
IAEItemStack configItem = configItems.getAEStackInSlot(i);
if (configItem != null) {
IAEItemStack is = configItem.copy();
if (invItem == null) requestItem(is, i);
else if (is.equals(invItem)) {
int confSize = (int) is.getStackSize();
if (invItem.stackSize < confSize / 2f) {
is.setStackSize(confSize - invItem.stackSize);
requestItem(is, i);
} else if (invItem.stackSize > confSize) {
returnItem(i, invItem.stackSize - confSize);
}
} else {
returnItem(i, Integer.MAX_VALUE);
}
} else if (invItem != null) {
returnItem(i, Integer.MAX_VALUE);
}
}
return TickRateModulation.SAME;
}
private void returnFluid(int index, long amount) {
try {
IAEFluidStack ias = invFluids.drain(index, amount, true);
storedFluidCount -= ias.getStackSize();
IAEFluidStack notInserted = this.getProxy().getStorage().getFluidInventory()
.injectItems(ias, Actionable.MODULATE, this.source);
if (notInserted != null) {
invFluids.fill(index, notInserted, true);
storedFluidCount += notInserted.getStackSize();
}
} catch (final GridAccessException ignored) {}
}
private void requestFluid(IAEFluidStack fs, int index) {
if (getRemainingFluidCount() == 0) return;
try {
long remFluid = getRemainingFluidCount();
if (fs.getStackSize() > remFluid) fs.setStackSize(remFluid);
IAEFluidStack extracted = this.getProxy().getStorage().getFluidInventory()
.extractItems(fs, Actionable.MODULATE, this.source);
if (extracted != null) {
storedFluidCount += extracted.getStackSize();
invFluids.fill(index, extracted, true);
}
} catch (final GridAccessException ignored) {}
}
private void returnItem(int index, int amount) {
try {
ItemStack is = invItems.getStackInSlot(index);
if (amount != Integer.MAX_VALUE) {
is.stackSize = is.stackSize - amount;
is = is.copy();
is.stackSize = amount;
storedItemCount -= is.stackSize;
} else {
invItems.setInventorySlotContents(index, null);
}
IAEItemStack notInserted = this.getProxy().getStorage().getItemInventory()
.injectItems(AEItemStack.create(is), Actionable.MODULATE, this.source);
if (notInserted != null) {
ItemStack tempStack = invItems.getStackInSlot(index);
if (tempStack != null) {
tempStack.stackSize = tempStack.stackSize + (int) notInserted.getStackSize();
storedItemCount += notInserted.getStackSize();
} else invItems.setInventorySlotContents(index, notInserted.getItemStack());
}
} catch (final GridAccessException ignored) {}
}
private void requestItem(IAEItemStack is, int index) {
if (getRemainingItemCount() == 0) return;
try {
long remItem = getRemainingItemCount();
if (is.getStackSize() > remItem) is.setStackSize(remItem);
IAEItemStack extracted = this.getProxy().getStorage().getItemInventory()
.extractItems(is, Actionable.MODULATE, this.source);
if (extracted != null) {
ItemStack tempStack = invItems.getStackInSlot(index);
if (tempStack != null) {
tempStack.stackSize = tempStack.stackSize + (int) extracted.getStackSize();
storedItemCount += extracted.getStackSize();
} else invItems.setInventorySlotContents(index, extracted.getItemStack());
}
} catch (final GridAccessException ignored) {}
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection whichSide) {
return IntStream.rangeClosed(0, 62).toArray();
}
@Nonnull
@Override
public IInventory getInternalInventory() {
return invItems;
}
public AppEngInternalAEInventory getConfigFluid() {
return configFluids;
}
public AppEngInternalAEInventory getConfigItems() {
return configItems;
}
public AppEngInternalInventory getCell() {
return cell;
}
public long getFreeBytes() {
return totalBytes - (((storedItemCount + getUnusedItemCount()) / 8)
+ ((storedFluidCount + getUnusedFluidCount()) / 2048));
}
public long getRemainingFluidCount() {
final double remaining = (double) getFreeBytes() * 2048 + this.getUnusedFluidCount();
if (remaining > Long.MAX_VALUE) return Long.MAX_VALUE;
return remaining > 0 ? (long) remaining : 0;
}
public int getUnusedFluidCount() {
final int div = (int) (storedFluidCount % 2048);
if (div == 0) {
return 0;
}
return 2048 - div;
}
public long getRemainingItemCount() {
final long remaining = getFreeBytes() * 8 + this.getUnusedItemCount();
return remaining > 0 ? remaining : 0;
}
public int getUnusedItemCount() {
final long div = storedItemCount % 8;
if (div == 0) {
return 0;
}
return (int) (8 - div);
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added) {
switch (mc) {
case setInventorySlotContents -> {
if (added != null) {
if (inv == cell) {
if (added.getItem() instanceof ItemBasicStorageCell ibsc) {
totalBytes = ibsc.getBytesLong(added);
} else if (added.getItem() instanceof FCBaseItemCell fcbic) {
totalBytes = fcbic.getBytes(added);
}
getProxy().setIdlePowerUsage(Math.sqrt(Math.pow(totalBytes, 0.576D)));
} else if (inv == invItems) {
storedItemCount += added.stackSize;
}
}
if (removed != null) {
if (inv == cell) {
totalBytes = 0;
getProxy().setIdlePowerUsage(4d);
} else if (inv == invItems) {
storedItemCount -= removed.stackSize;
}
}
}
case decreaseStackSize -> {
if (inv == cell) {
totalBytes = 0;
getProxy().setIdlePowerUsage(4d);
}
if (inv == invItems) {
storedItemCount -= removed.stackSize;
}
}
case markDirty -> {}
}
try {
getProxy().getTick().alertDevice(getProxy().getNode());
} catch (GridAccessException e) {
AELog.error(e, "Couldn't wake up level emitter for delayed updates");
}
markForUpdate();
}
public void fullRefund() {
for (int i = 0; i < 9; i++) {
if (invFluids.getFluidStackInSlot(i) != null) {
returnFluid(i, Long.MAX_VALUE);
}
}
for (int i = 0; i < 63; i++) {
if (invItems.getStackInSlot(i) != null) {
returnItem(i, Integer.MAX_VALUE);
}
}
}
@Override
public void getDrops(World w, int x, int y, int z, List<ItemStack> drops) {
if (cell.getStackInSlot(0) != null) drops.add(cell.getStackInSlot(0));
for (int i = 0; i < 9; i++) {
ItemStack ifp = ItemFluidPacket.newStack(invFluids.getFluidStackInSlot(i));
if (ifp != null) drops.add(ifp);
}
super.getDrops(w, x, y, z, drops);
}
@Override
public boolean canInsertItem(int slotIndex, ItemStack insertingItem, int side) {
return false;
}
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
return 0;
}
@Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
FluidStack fs = invFluids.drain(from, resource, doDrain);
if (doDrain && fs != null) storedFluidCount -= fs.amount;
return fs;
}
@Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
FluidStack fs = invFluids.drain(from, maxDrain, doDrain);
if (doDrain && fs != null) storedFluidCount -= fs.amount;
return fs;
}
@Override
public boolean canFill(ForgeDirection from, Fluid fluid) {
return false;
}
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid) {
return invFluids.canDrain(from, fluid);
}
@Override
public FluidTankInfo[] getTankInfo(ForgeDirection from) {
return invFluids.getTankInfo(from);
}
@Override
public void onFluidInventoryChanged(IAEFluidTank inv, int slot) {
saveChanges();
markForUpdate();
}
@Override
public AEFluidInventory getInternalFluid() {
return this.invFluids;
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileSuperStockReplenisher(final ByteBuf data) {
final boolean oldPower = isPowered;
isPowered = data.readBoolean();
return isPowered != oldPower;
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileSuperStockReplenisher(final ByteBuf data) {
data.writeBoolean(isActive());
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBTEvent(NBTTagCompound data) {
invItems.readFromNBT(data, "ItemInv");
invFluids.readFromNBT(data, "FluidInv");
configItems.readFromNBT(data, "configItems");
configFluids.readFromNBT(data, "configFluids");
cell.readFromNBT(data, "cellHolder");
totalBytes = data.getLong("totalBytes");
storedFluidCount = data.getLong("storedFluidCount");
storedItemCount = data.getLong("storedItemCount");
getProxy().setIdlePowerUsage(data.getDouble("powerDraw"));
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public NBTTagCompound writeToNBTEvent(NBTTagCompound data) {
invItems.writeToNBT(data, "ItemInv");
invFluids.writeToNBT(data, "FluidInv");
configItems.writeToNBT(data, "configItems");
configFluids.writeToNBT(data, "configFluids");
cell.writeToNBT(data, "cellHolder");
data.setLong("totalBytes", totalBytes);
data.setLong("storedFluidCount", storedFluidCount);
data.setLong("storedItemCount", storedItemCount);
data.setDouble("powerDraw", getProxy().getIdlePowerUsage());
return data;
}
@MENetworkEventSubscribe
public void stateChange(final MENetworkPowerStatusChange p) {
this.updatePowerState();
}
@MENetworkEventSubscribe
public final void bootingRender(final MENetworkBootingStatusChange c) {
this.updatePowerState();
}
@Override
public boolean isPowered() {
return this.isPowered;
}
@Override
public boolean isActive() {
return this.isPowered;
}
private void updatePowerState() {
boolean newState = false;
try {
newState = this.getProxy().isActive()
&& this.getProxy().getEnergy().extractAEPower(1, Actionable.SIMULATE, PowerMultiplier.CONFIG)
> 0.0001;
} catch (final GridAccessException ignored) {}
if (newState != this.isPowered) {
this.isPowered = newState;
this.markForUpdate();
}
}
@Override
public DimensionalCoord getLocation() {
return new DimensionalCoord(this);
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir) {
return AECableType.SMART;
}
@Override
public TickingRequest getTickingRequest(IGridNode node) {
return new TickingRequest(120, 120, false, false);
}
@Override
public TickRateModulation tickingRequest(IGridNode node, int TicksSinceLastCall) {
return doWork();
}
}
@@ -1,7 +1,5 @@
package com.glodblock.github.coremod.registries.adapters;
import static com.glodblock.github.coremod.registries.adapters.PartLevelEmitterAdapter.getPatchedInventory;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
@@ -9,8 +7,9 @@ import net.minecraftforge.common.util.ForgeDirection;
import com.glodblock.github.api.registries.ILevelViewable;
import com.glodblock.github.api.registries.ILevelViewableAdapter;
import com.glodblock.github.api.registries.LevelItemInfo;
import com.glodblock.github.api.registries.LevelState;
import com.glodblock.github.common.parts.PartFluidLevelEmitter;
import com.glodblock.github.common.tile.TileLevelMaintainer.State;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
@@ -45,10 +44,7 @@ public class PartFluidLevelEmitterAdapter implements ILevelViewable, ILevelViewa
@Override
public IInventory getInventoryByName(String name) {
long value = delegate.getReportingValue();
State state = delegate.isProvidingStrongPower() > 0 ? State.Craft : State.Idle;
return getPatchedInventory(delegate.getInventoryByName(name), value, state);
return delegate.getInventoryByName(name);
}
@Override
@@ -82,7 +78,13 @@ public class PartFluidLevelEmitterAdapter implements ILevelViewable, ILevelViewa
}
@Override
public ItemStack getSelfItemStack() {
return delegate.getItemStack();
public LevelItemInfo[] getLevelItemInfoList() {
ItemStack stack = delegate.getInventoryByName("config").getStackInSlot(0);
if (stack == null) return new LevelItemInfo[] { null };
return new LevelItemInfo[] { new LevelItemInfo(
stack,
delegate.getReportingValue(),
-1,
delegate.isProvidingStrongPower() > 0 ? LevelState.Craft : LevelState.Idle) };
}
}
@@ -2,34 +2,24 @@ package com.glodblock.github.coremod.registries.adapters;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import org.jetbrains.annotations.NotNull;
import com.glodblock.github.api.registries.ILevelViewable;
import com.glodblock.github.api.registries.ILevelViewableAdapter;
import com.glodblock.github.common.tile.TileLevelMaintainer.State;
import com.glodblock.github.common.tile.TileLevelMaintainer.TLMTags;
import com.glodblock.github.inventory.AeItemStackHandler;
import com.glodblock.github.inventory.AeStackInventoryImpl;
import com.glodblock.github.api.registries.LevelItemInfo;
import com.glodblock.github.api.registries.LevelState;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.parts.automation.PartLevelEmitter;
import appeng.util.item.AEItemStack;
public class PartLevelEmitterAdapter implements ILevelViewable, ILevelViewableAdapter {
private PartLevelEmitter delegate;
private static final int SLOT_IN = 0;
public PartLevelEmitterAdapter() {}
public ILevelViewable adapt(IGridHost gridHost) {
@@ -37,21 +27,6 @@ public class PartLevelEmitterAdapter implements ILevelViewable, ILevelViewableAd
return this;
}
@NotNull
static public IInventory getPatchedInventory(IInventory inventory, long quantity, State state) {
ItemStack itemStack = inventory.getStackInSlot(SLOT_IN);
if (itemStack == null) return inventory;
NBTTagCompound data = !itemStack.hasTagCompound() ? new NBTTagCompound() : itemStack.getTagCompound();
data.setLong(TLMTags.Quantity.tagName, quantity);
data.setInteger(TLMTags.State.tagName, state.ordinal());
itemStack.setTagCompound(data);
AeStackInventoryImpl<IAEItemStack> inv = new AeStackInventoryImpl<>(StorageChannel.ITEMS, 1);
inv.setStack(SLOT_IN, AEItemStack.create(itemStack));
return new AeItemStackHandler(inv);
}
@Override
public DimensionalCoord getLocation() {
return delegate.getLocation();
@@ -64,10 +39,7 @@ public class PartLevelEmitterAdapter implements ILevelViewable, ILevelViewableAd
@Override
public IInventory getInventoryByName(String name) {
long value = delegate.getReportingValue();
State state = delegate.isProvidingStrongPower() > 0 ? State.Craft : State.Idle;
return getPatchedInventory(delegate.getInventoryByName(name), value, state);
return delegate.getInventoryByName(name);
}
@Override
@@ -106,12 +78,13 @@ public class PartLevelEmitterAdapter implements ILevelViewable, ILevelViewableAd
}
@Override
public ItemStack getSelfItemStack() {
return delegate.getItemStack();
}
@Override
public ItemStack getDisplayItemStack() {
return delegate.getCrafterIcon();
public LevelItemInfo[] getLevelItemInfoList() {
ItemStack stack = delegate.getInventoryByName("config").getStackInSlot(0);
if (stack == null) return new LevelItemInfo[] { null };
return new LevelItemInfo[] { new LevelItemInfo(
stack,
delegate.getReportingValue(),
-1,
delegate.isProvidingStrongPower() > 0 ? LevelState.Craft : LevelState.Idle) };
}
}
@@ -14,7 +14,9 @@ import net.minecraft.world.World;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.common.item.FCBaseItem;
import com.glodblock.github.util.ModAndClassUtil;
import codechicken.nei.api.API;
import cpw.mods.fml.common.registry.GameRegistry;
/**
@@ -38,6 +40,10 @@ public class ProxyItem extends FCBaseItem {
@Override
public FCBaseItem register() {
GameRegistry.registerItem(this, "ec2placeholder." + name, FluidCraft.MODID);
if (!ModAndClassUtil.EC2) {
API.hideItem("ec2placeholder." + name);
}
return this;
}
@@ -6,10 +6,10 @@ import net.minecraft.item.ItemStack;
import com.glodblock.github.api.FluidCraftAPI;
import com.glodblock.github.common.storage.IStorageFluidCell;
import com.glodblock.github.crossmod.extracells.ProxyItem;
import com.glodblock.github.inventory.FluidCellConfig;
import appeng.api.config.FuzzyMode;
import appeng.api.storage.data.IAEFluidStack;
import appeng.items.contents.CellConfig;
import appeng.items.contents.CellUpgrades;
import appeng.util.Platform;
@@ -88,7 +88,7 @@ public class ProxyFluidStorageCell extends ProxyItem implements IStorageFluidCel
@Override
public IInventory getConfigInventory(ItemStack is) {
return new CellConfig(is);
return new FluidCellConfig(is);
}
@Override
@@ -61,7 +61,7 @@ public class DriverLevelMaintainer extends DriverSidedTileEntity {
if (slot < 0 || slot >= TileLevelMaintainer.REQ_COUNT) {
throw new IllegalArgumentException("Invalid slot");
}
return tileEntity.requests.isDone(slot);
return tileEntity.isDone(slot);
}
private boolean isEnable(Arguments args) {
@@ -69,7 +69,7 @@ public class DriverLevelMaintainer extends DriverSidedTileEntity {
if (slot < 0 || slot >= TileLevelMaintainer.REQ_COUNT) {
throw new IllegalArgumentException("Invalid slot");
}
return tileEntity.requests.isEnable(slot);
return tileEntity.requests[slot].isEnable();
}
private boolean setEnable(Arguments args) {
@@ -81,7 +81,7 @@ public class DriverLevelMaintainer extends DriverSidedTileEntity {
throw new IllegalArgumentException("Invalid slot");
}
boolean enable = args.checkBoolean(1);
tileEntity.requests.updateStatus(slot, enable);
tileEntity.updateStatus(slot, enable);
return true;
}
}
@@ -103,12 +103,12 @@ public class DriverLevelMaintainer extends DriverSidedTileEntity {
result.put("label", stack.getDisplayName());
result.put("maxDamage", stack.getMaxDamage());
result.put("name", GameRegistry.findUniqueIdentifierFor(stack.getItem()).toString());
result.put("quantity", tileEntity.requests.getQuantity(slot));
result.put("batch", tileEntity.requests.getBatchSize(slot));
result.put("quantity", tileEntity.requests[slot].getQuantity());
result.put("batch", tileEntity.requests[slot].getBatchSize());
result.put("isFluid", ItemFluidDrop.isFluidStack(stack));
if (ItemFluidDrop.isFluidStack(stack)) result.put("fluid", ItemFluidDrop.getFluidStack(stack));
result.put("isEnable", tileEntity.requests.isEnable(slot));
result.put("isDone", tileEntity.requests.isDone(slot));
result.put("isEnable", tileEntity.requests[slot].isEnable());
result.put("isDone", tileEntity.isDone(slot));
return new Object[] { result };
}
return new Object[] { null };
@@ -122,7 +122,7 @@ public class DriverLevelMaintainer extends DriverSidedTileEntity {
if (dbStack == null) {
throw new IllegalArgumentException("Invalid slot");
}
tileEntity.requests.updateStack(slot, dbStack);
tileEntity.updateStack(slot, dbStack);
} else {
throw new IllegalArgumentException("Not a database");
}
@@ -5,13 +5,14 @@ import java.util.List;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import com.glodblock.github.common.tile.TileLevelMaintainer;
import com.glodblock.github.crossmod.waila.Tooltip;
import appeng.api.storage.data.IAEItemStack;
import appeng.integration.modules.waila.BaseWailaDataProvider;
import mcp.mobius.waila.api.IWailaConfigHandler;
import mcp.mobius.waila.api.IWailaDataAccessor;
@@ -23,16 +24,24 @@ public class LevelMaintainerWailaDataProvider extends BaseWailaDataProvider {
final IWailaDataAccessor accessor, final IWailaConfigHandler config) {
final TileEntity te = accessor.getTileEntity();
if (te instanceof TileLevelMaintainer tileLevelMaintainer) {
te.readFromNBT(accessor.getNBTData());
for (int i = 0; i < TileLevelMaintainer.REQ_COUNT; i++) {
IAEItemStack ias = tileLevelMaintainer.requests.getAEItemStack(i);
if (ias != null) {
currentToolTip.add(
Tooltip.tileLevelMaintainerFormat(
ias.getItemStack().getDisplayName(),
tileLevelMaintainer.requests.getQuantity(i),
tileLevelMaintainer.requests.getBatchSize(i),
tileLevelMaintainer.requests.isEnable(i)));
NBTTagCompound data = accessor.getNBTData();
if (data.hasKey(TileLevelMaintainer.NBT_REQUESTS)) {
NBTTagList tagList = data.getTagList(TileLevelMaintainer.NBT_REQUESTS, Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < tagList.tagCount(); i++) {
NBTTagCompound tag = tagList.getCompoundTagAt(i);
if (tag == null || !tag.hasKey(TileLevelMaintainer.NBT_STACK)) continue;
try {
TileLevelMaintainer.RequestInfo request = new TileLevelMaintainer.RequestInfo(
tag,
tileLevelMaintainer);
currentToolTip.add(
Tooltip.tileLevelMaintainerFormat(
request.getAEItemStack().getItemStack().getDisplayName(),
request.getQuantity(),
request.getBatchSize(),
request.isEnable()));
} catch (Exception ignored) {}
}
}
}
@@ -22,12 +22,21 @@ public class AEFluidInventory implements IAEFluidTank {
private final IAEFluidStack[] fluids;
private final IAEFluidInventory handler;
private final int capacity;
private final long capacityLong;
public int lastIndex;
public AEFluidInventory(final IAEFluidInventory handler, final int slots, final int capcity) {
this.fluids = new IAEFluidStack[slots];
this.handler = handler;
this.capacity = capcity;
this.capacityLong = capcity;
}
public AEFluidInventory(final IAEFluidInventory handler, final int slots, final long capcity) {
this.fluids = new IAEFluidStack[slots];
this.handler = handler;
this.capacity = Integer.MAX_VALUE;
this.capacityLong = capcity;
}
public AEFluidInventory(final IAEFluidInventory handler, final int slots) {
@@ -122,6 +131,37 @@ public class AEFluidInventory implements IAEFluidTank {
return amountToStore;
}
public long fill(final int slot, final IAEFluidStack resource, final boolean doFill) {
if (resource == null || resource.getStackSize() <= 0) {
return 0;
}
final IAEFluidStack fluid = this.fluids[slot];
if (fluid != null && !(fluid.getFluid() == resource.getFluid())) {
return 0;
}
long amountToStore = this.capacityLong;
if (fluid != null) {
amountToStore -= fluid.getStackSize();
}
amountToStore = Math.min(amountToStore, resource.getStackSize());
if (doFill) {
if (fluid == null) {
this.setFluidInSlot(slot, resource);
} else {
fluid.setStackSize(fluid.getStackSize() + amountToStore);
this.onContentChanged(slot);
}
}
return amountToStore;
}
public FluidStack drain(final int slot, final FluidStack resource, final boolean doDrain) {
final IAEFluidStack fluid = this.fluids[slot];
if (fluid == null || !fluid.getFluidStack().isFluidEqual(resource)) {
@@ -152,6 +192,28 @@ public class AEFluidInventory implements IAEFluidTank {
return stack;
}
public IAEFluidStack drain(final int slot, final long maxDrain, boolean doDrain) {
final IAEFluidStack fluid = this.fluids[slot];
if (fluid == null || maxDrain <= 0) {
return null;
}
long drained = maxDrain;
if (fluid.getStackSize() < drained) {
drained = fluid.getStackSize();
}
IAEFluidStack stack = fluid.copy().setStackSize(drained);
if (doDrain) {
fluid.setStackSize(fluid.getStackSize() - drained);
if (fluid.getStackSize() <= 0) {
this.fluids[slot] = null;
}
this.onContentChanged(slot);
}
return stack;
}
@Override
public int fill(ForgeDirection from, final FluidStack fluid, final boolean doFill) {
if (fluid == null || fluid.amount <= 0) {
@@ -0,0 +1,27 @@
package com.glodblock.github.inventory;
import net.minecraft.item.ItemStack;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.util.Util;
import appeng.items.contents.CellConfig;
public class FluidCellConfig extends CellConfig {
public FluidCellConfig(ItemStack is) {
super(is);
}
@Override
public void setInventorySlotContents(int slot, ItemStack newItemStack) {
if (newItemStack != null && !(newItemStack.getItem() instanceof ItemFluidPacket)) {
ItemStack fluidPacket = ItemFluidPacket.newDisplayStack(Util.getFluidFromItem(newItemStack));
if (fluidPacket != null) {
super.setInventorySlotContents(slot, fluidPacket);
return;
}
}
super.setInventorySlotContents(slot, newItemStack);
}
}
@@ -5,6 +5,7 @@ import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import com.glodblock.github.client.gui.GuiCraftingStatus;
import com.glodblock.github.client.gui.GuiDualInterface;
@@ -39,6 +40,7 @@ import com.glodblock.github.client.gui.GuiPatternItemRenamer;
import com.glodblock.github.client.gui.GuiPatternMulti;
import com.glodblock.github.client.gui.GuiPatternValueAmount;
import com.glodblock.github.client.gui.GuiRenamer;
import com.glodblock.github.client.gui.GuiSuperStockReplenisher;
import com.glodblock.github.client.gui.container.ContainerCraftingWireless;
import com.glodblock.github.client.gui.container.ContainerDualInterface;
import com.glodblock.github.client.gui.container.ContainerEssentiaMonitor;
@@ -68,6 +70,7 @@ import com.glodblock.github.client.gui.container.ContainerOCPatternEditor;
import com.glodblock.github.client.gui.container.ContainerPatternMulti;
import com.glodblock.github.client.gui.container.ContainerPatternValueAmount;
import com.glodblock.github.client.gui.container.ContainerRenamer;
import com.glodblock.github.client.gui.container.ContainerSuperStockReplenisher;
import com.glodblock.github.common.parts.PartFluidLevelEmitter;
import com.glodblock.github.common.parts.PartFluidStorageBus;
import com.glodblock.github.common.parts.base.FCPart;
@@ -79,6 +82,7 @@ import com.glodblock.github.common.tile.TileIngredientBuffer;
import com.glodblock.github.common.tile.TileLargeIngredientBuffer;
import com.glodblock.github.common.tile.TileLevelMaintainer;
import com.glodblock.github.common.tile.TileOCPatternEditor;
import com.glodblock.github.common.tile.TileSuperStockReplenisher;
import com.glodblock.github.inventory.IDualHost;
import com.glodblock.github.inventory.item.IFluidPortableCell;
import com.glodblock.github.inventory.item.IWirelessTerminal;
@@ -519,6 +523,18 @@ public enum GuiType {
return new GuiPatternValueAmount(player.inventory, inv);
}
}),
PATTERN_VALUE_SET_TILE(new TileGuiFactory<>(TileEntity.class) {
@Override
protected Object createServerGui(EntityPlayer player, TileEntity inv) {
return new ContainerPatternValueAmount(player.inventory, inv);
}
@Override
protected Object createClientGui(EntityPlayer player, TileEntity inv) {
return new GuiPatternValueAmount(player.inventory, inv);
}
}),
GUI_PATTERN_MULTI(new PartOrItemGuiFactory<>(ITerminalHost.class) {
@@ -557,6 +573,19 @@ public enum GuiType {
protected Object createClientGui(EntityPlayer player, ITerminalHost inv) {
return new GuiMagnetFilter(player.inventory, inv);
}
}),
GUI_SUPER_STOCK_REPLENISHER(new TileGuiFactory<>(TileSuperStockReplenisher.class) {
@Override
protected Object createServerGui(EntityPlayer player, TileSuperStockReplenisher inv) {
return new ContainerSuperStockReplenisher(player.inventory, inv);
}
@Override
protected Object createClientGui(EntityPlayer player, TileSuperStockReplenisher inv) {
return new GuiSuperStockReplenisher(player.inventory, inv);
}
});
public static final List<GuiType> VALUES = ImmutableList.copyOf(values());
@@ -16,20 +16,25 @@ import com.glodblock.github.util.Util;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.implementations.items.IAEItemPowerStorage;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode;
import appeng.api.networking.security.PlayerSource;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.ITerminalPins;
import appeng.api.storage.MEMonitorHandler;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.util.AECableType;
import appeng.items.contents.PinsHandler;
import appeng.items.contents.PinsHolder;
import appeng.items.tools.powered.ToolWirelessTerminal;
import appeng.me.storage.NullInventory;
import appeng.util.Platform;
public abstract class BaseWirelessInventory extends MEMonitorHandler implements IWirelessTerminal, IWirelessExtendCard {
public abstract class BaseWirelessInventory extends MEMonitorHandler
implements IWirelessTerminal, IWirelessExtendCard, ITerminalPins {
protected final ItemStack target;
protected final IAEItemPowerStorage ips;
@@ -42,17 +47,20 @@ public abstract class BaseWirelessInventory extends MEMonitorHandler implements
protected WirelessMagnet.Mode magnetMode = WirelessMagnet.Mode.Off;
protected EntityPlayer player;
protected boolean restock;
private final PinsHolder pinsInv;
@SuppressWarnings("unchecked")
public BaseWirelessInventory(final ItemStack is, final int slot, IGridNode gridNode, EntityPlayer player,
StorageChannel channel) {
super(Objects.requireNonNull(Util.getWirelessInv(is, player, channel)));
this.player = player;
this.ips = (ToolWirelessTerminal) is.getItem();
this.grid = gridNode;
this.target = is;
this.inventorySlot = slot;
this.channel = channel;
this.source = new PlayerSource(player, this);
pinsInv = new PinsHolder(is);
this.readFromNBT();
}
@@ -60,18 +68,20 @@ public abstract class BaseWirelessInventory extends MEMonitorHandler implements
public BaseWirelessInventory(final ItemStack is, final int slot, IGridNode gridNode, EntityPlayer player,
StorageChannel channel, boolean nullInventory) {
super(new NullInventory<>());
this.player = player;
this.ips = (ToolWirelessTerminal) is.getItem();
this.grid = gridNode;
this.target = is;
this.inventorySlot = slot;
this.channel = channel;
this.source = new PlayerSource(player, this);
pinsInv = new PinsHolder(is);
this.readFromNBT();
}
private void readFromNBT() {
NBTTagCompound data = Platform.openNbtData(this.target);
this.setMagnetCardMode(WirelessMagnet.Mode.values()[data.getInteger(modeKey)]);
this.setMagnetCardMode(WirelessMagnet.Mode.getModes()[data.getInteger(modeKey)]);
this.setRestock(data.getBoolean(ItemBaseWirelessTerminal.restockItems));
}
@@ -137,9 +147,8 @@ public abstract class BaseWirelessInventory extends MEMonitorHandler implements
}
public void setMagnetCardNextMode() {
setMagnetCardMode(
WirelessMagnet.Mode.values()[(getMagnetCardMode().ordinal() + 1)
% WirelessMagnet.Mode.values().length]);
final WirelessMagnet.Mode[] MODES = WirelessMagnet.Mode.getModes();
setMagnetCardMode(MODES[(getMagnetCardMode().ordinal() + 1) % MODES.length]);
}
public void setRestock(boolean val) {
@@ -183,4 +192,14 @@ public abstract class BaseWirelessInventory extends MEMonitorHandler implements
data.setBoolean(restockItems, this.restock);
data.setInteger(modeKey, this.getMagnetCardMode().ordinal());
}
@Override
public PinsHandler getPinsHandler(EntityPlayer player) {
return pinsInv.getHandler(player);
}
@Override
public IGrid getGrid() {
return grid != null ? grid.getGrid() : null;
}
}
@@ -2,7 +2,6 @@ package com.glodblock.github.inventory.item;
import static com.glodblock.github.common.Config.magnetRange;
import java.util.Iterator;
import java.util.List;
import net.minecraft.entity.item.EntityItem;
@@ -12,9 +11,12 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerPickupXpEvent;
import com.glodblock.github.common.item.ItemWirelessUltraTerminal;
import appeng.entity.EntityFloatingItem;
import appeng.util.Platform;
public class WirelessMagnet {
@@ -24,9 +26,16 @@ public class WirelessMagnet {
public static String filterConfigKey = "MagnetConfig";
public enum Mode {
Off,
Inv,
ME
ME;
private static final Mode[] MODES = Mode.values();
public static Mode[] getModes() {
return MODES;
}
}
public enum ListMode {
@@ -34,7 +43,7 @@ public class WirelessMagnet {
BlackList
}
public static List<?> getEntitiesInRange(Class<?> entityType, World world, int x, int y, int z, int distance) {
private static <T> List<T> getEntitiesInRange(Class<T> entityType, World world, int x, int y, int z, int distance) {
return world.getEntitiesWithinAABB(
entityType,
AxisAlignedBB.getBoundingBox(
@@ -46,75 +55,87 @@ public class WirelessMagnet {
z + distance));
}
@SuppressWarnings("unchecked")
public static boolean isConfigured(ItemStack wirelessTerm) {
NBTTagCompound data = Platform.openNbtData(wirelessTerm);
return data.hasKey(modeKey);
}
public static void doMagnet(ItemStack wirelessTerm, World world, EntityPlayer player) {
if (wirelessTerm == null || player == null || player.isSneaking() || !isConfigured(wirelessTerm)) return;
Iterator<?> iterator = getEntitiesInRange(
// This method uses the same algorithm as the magnet from draconic evolution
// if changes are ever made, they should be made on both
public static void doMagnet(ItemStack wirelessTerm, EntityPlayer player) {
if (player.ticksExisted % 5 != 0 || player.isSneaking() || !isConfigured(wirelessTerm)) return;
World world = player.worldObj;
final List<EntityItem> items = getEntitiesInRange(
EntityItem.class,
world,
(int) player.posX,
(int) player.posY,
(int) player.posZ,
magnetRange).iterator();
magnetRange);
final boolean skipPlayerCheck = world.playerEntities.size() < 2;
boolean playSound = false;
// account for the server/client desync
double playerEyesPos = player.posY
+ (world.isRemote ? player.getEyeHeight() - player.getDefaultEyeHeight() : player.getEyeHeight());
while (iterator.hasNext()) {
EntityItem itemToGet = (EntityItem) iterator.next();
EntityPlayer closestPlayer = world.getClosestPlayerToEntity(itemToGet, magnetRange);
if (closestPlayer != null && closestPlayer == player) {
NBTTagCompound itemNBT = new NBTTagCompound();
itemToGet.writeEntityToNBT(itemNBT);
if (itemToGet.func_145800_j() == null
|| !itemToGet.func_145800_j().equals(player.getCommandSenderName()))
itemToGet.delayBeforeCanPickup = 0;
if (itemToGet.delayBeforeCanPickup <= 0) {
itemNBT.setBoolean("attractable", true);
itemToGet.readEntityFromNBT(itemNBT);
}
if (itemNBT.getBoolean("attractable")) {
itemToGet.motionX = itemToGet.motionY = itemToGet.motionZ = 0;
itemToGet.setPosition(
player.posX - 0.2 + (world.rand.nextDouble() * 0.4),
player.posY - 0.6,
player.posZ - 0.2 + (world.rand.nextDouble() * 0.4));
}
for (EntityItem itemToGet : items) {
if (itemToGet.getEntityItem() == null || itemToGet instanceof EntityFloatingItem) {
continue;
}
if (!skipPlayerCheck) {
EntityPlayer closestPlayer = world.getClosestPlayerToEntity(itemToGet, magnetRange);
if (closestPlayer == null || closestPlayer != player) continue;
}
if (itemToGet.delayBeforeCanPickup > 0) {
itemToGet.delayBeforeCanPickup = 0;
}
playSound = true;
itemToGet.motionX = 0;
itemToGet.motionY = 0;
itemToGet.motionZ = 0;
itemToGet.setPosition(
player.posX - 0.2 + (world.rand.nextDouble() * 0.4),
playerEyesPos - 0.62,
player.posZ - 0.2 + (world.rand.nextDouble() * 0.4));
}
// xp
iterator = getEntitiesInRange(
EntityXPOrb.class,
world,
(int) player.posX,
(int) player.posY,
(int) player.posZ,
magnetRange).iterator();
while (iterator.hasNext()) {
EntityXPOrb xpToGet = (EntityXPOrb) iterator.next();
EntityPlayer closestPlayer = world.getClosestPlayerToEntity(xpToGet, magnetRange);
if (playSound) {
world.playSoundAtEntity(
player,
"random.orb",
0.1F,
0.5F * ((world.rand.nextFloat() - world.rand.nextFloat()) * 0.7F + 2F));
}
if (!xpToGet.isDead && !xpToGet.isInvisible() && closestPlayer != null && closestPlayer == player) {
int xpAmount = xpToGet.xpValue;
xpToGet.xpValue = 0;
player.xpCooldown = 0;
player.addExperience(xpAmount);
xpToGet.setDead();
xpToGet.setInvisible(true);
world.playSoundAtEntity(
player,
"random.orb",
0.08F,
0.5F * ((world.rand.nextFloat() - world.rand.nextFloat()) * 0.7F + 1.8F));
if (!world.isRemote) {
// xp
final List<EntityXPOrb> xpOrbs = getEntitiesInRange(
EntityXPOrb.class,
world,
(int) player.posX,
(int) player.posY,
(int) player.posZ,
magnetRange);
for (EntityXPOrb xpToGet : xpOrbs) {
if (xpToGet.field_70532_c == 0 && xpToGet.isEntityAlive()) {
if (!skipPlayerCheck) {
EntityPlayer closestPlayer = world.getClosestPlayerToEntity(xpToGet, magnetRange);
if (closestPlayer == null || closestPlayer != player) continue;
}
if (MinecraftForge.EVENT_BUS.post(new PlayerPickupXpEvent(player, xpToGet))) continue;
world.playSoundAtEntity(
player,
"random.orb",
0.1F,
0.5F * ((world.rand.nextFloat() - world.rand.nextFloat()) * 0.7F + 1.8F));
player.onItemPickup(xpToGet, 1);
player.addExperience(xpToGet.xpValue);
xpToGet.setDead();
}
}
}
}
@@ -123,7 +144,7 @@ public class WirelessMagnet {
if (is != null && is.getItem() instanceof ItemWirelessUltraTerminal) {
NBTTagCompound data = Platform.openNbtData(is);
if (data.hasKey(modeKey)) {
return Mode.values()[data.getInteger(modeKey)];
return Mode.getModes()[data.getInteger(modeKey)];
}
setMode(is, Mode.Off);
}
@@ -13,7 +13,6 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import com.glodblock.github.inventory.ItemBiggerAppEngInventory;
@@ -210,19 +209,11 @@ public class WirelessMagnetCardFilterInventory extends BaseWirelessInventory imp
return null;
}
public boolean doInject(IAEItemStack is, EntityItem itemToGet, World world) {
public boolean doInject(IAEItemStack is, EntityItem itemToGet) {
IAEItemStack ais = (IAEItemStack) injectItems(is);
if (ais != null) {
player.onItemPickup(itemToGet, ais.getItemStack().stackSize);
player.inventory.addItemStackToInventory(ais.getItemStack());
world.playSoundAtEntity(
player,
"random.pop",
0.15F,
((world.rand.nextFloat() - world.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F);
return false;
}
return true;
if (ais == null) return true;
itemToGet.getEntityItem().stackSize = (int) ais.getStackSize();
return false;
}
public boolean isItemFiltered(ItemStack inputItemStack) {
@@ -0,0 +1,28 @@
package com.glodblock.github.inventory.slot;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.util.Util;
import appeng.container.slot.IOptionalSlotHost;
import appeng.container.slot.OptionalSlotFake;
public class OptionalFluidSlotFake extends OptionalSlotFake {
public OptionalFluidSlotFake(final IInventory inv, final IOptionalSlotHost containerBus, final int idx, final int x,
final int y, final int offX, final int offY, final int groupNum) {
super(inv, containerBus, idx, x, y, offX, offY, groupNum);
}
@Override
public void putStack(ItemStack is) {
if (is == null) super.putStack(null);
FluidStack fluidStack = Util.getFluidFromItem(is);
if (fluidStack != null) {
super.putStack(ItemFluidPacket.newStack(fluidStack));
}
}
}
@@ -20,12 +20,14 @@ import com.glodblock.github.network.CPacketSwitchGuis;
import com.glodblock.github.network.CPacketTransferRecipe;
import com.glodblock.github.network.CPacketValueConfig;
import com.glodblock.github.network.SPacketFluidUpdate;
import com.glodblock.github.network.SPacketLevelMaintainerGuiUpdate;
import com.glodblock.github.network.SPacketLevelTerminalUpdate;
import com.glodblock.github.network.SPacketMEFluidInvUpdate;
import com.glodblock.github.network.SPacketMEItemInvUpdate;
import com.glodblock.github.network.SPacketPatternItemRenamer;
import com.glodblock.github.network.SPacketSetItemAmount;
import com.glodblock.github.network.SPacketStringUpdate;
import com.glodblock.github.network.SPacketSuperStockReplenisherUpdate;
import com.glodblock.github.network.SPacketSwitchBack;
import com.glodblock.github.network.wrapper.FCNetworkWrapper;
@@ -60,6 +62,11 @@ public class ChannelLoader implements Runnable {
netHandler.registerMessage(new CPacketTransferRecipe.Handler(), CPacketTransferRecipe.class, id++, Side.SERVER);
netHandler.registerMessage(new CPacketDumpTank.Handler(), CPacketDumpTank.class, id++, Side.SERVER);
netHandler.registerMessage(new SPacketFluidUpdate.Handler(), SPacketFluidUpdate.class, id++, Side.CLIENT);
netHandler.registerMessage(
new SPacketSuperStockReplenisherUpdate.Handler(),
SPacketSuperStockReplenisherUpdate.class,
id++,
Side.CLIENT);
netHandler
.registerMessage(new CPacketPatternValueSet.Handler(), CPacketPatternValueSet.class, id++, Side.SERVER);
netHandler.registerMessage(new CPacketValueConfig.Handler(), CPacketValueConfig.class, id++, Side.SERVER);
@@ -87,6 +94,11 @@ public class ChannelLoader implements Runnable {
SPacketPatternItemRenamer.class,
id++,
Side.SERVER);
netHandler.registerMessage(
new SPacketLevelMaintainerGuiUpdate.Handler(),
SPacketLevelMaintainerGuiUpdate.class,
id++,
Side.CLIENT);
}
public static void sendPacketToAllPlayers(Packet packet, World world) {
@@ -14,6 +14,7 @@ import com.glodblock.github.common.block.BlockIngredientBuffer;
import com.glodblock.github.common.block.BlockLargeIngredientBuffer;
import com.glodblock.github.common.block.BlockLevelMaintainer;
import com.glodblock.github.common.block.BlockOCPatternEditor;
import com.glodblock.github.common.block.BlockSuperStockReplenisher;
import com.glodblock.github.common.block.BlockWalrus;
import com.glodblock.github.common.item.ItemBasicFluidStorageCell;
import com.glodblock.github.common.item.ItemBasicFluidStoragePart;
@@ -65,6 +66,7 @@ public class ItemAndBlockHolder {
public static BlockLargeIngredientBuffer LARGE_BUFFER = new BlockLargeIngredientBuffer().register();
public static BlockOCPatternEditor OC_EDITOR = new BlockOCPatternEditor().register();
public static BlockWalrus WALRUS = new BlockWalrus().register();
public static BlockSuperStockReplenisher SUPER_STOCK_RERPLENISHER = new BlockSuperStockReplenisher().register();
public static ItemFluidDrop DROP = new ItemFluidDrop().register();
public static ItemFluidEncodedPattern PATTERN = new ItemFluidEncodedPattern().register();
public static ItemPartFluidTerminal FLUID_TERM = new ItemPartFluidTerminal().register();
@@ -1,5 +1,6 @@
package com.glodblock.github.nei;
import java.util.ArrayList;
import java.util.regex.Pattern;
import net.minecraft.item.ItemStack;
@@ -10,9 +11,15 @@ import com.glodblock.github.common.storage.IFluidCellInventoryHandler;
import com.glodblock.github.common.storage.IStorageFluidCell;
import appeng.api.AEApi;
import appeng.api.implementations.items.IStorageCell;
import appeng.api.storage.ICellInventory;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.me.storage.CellInventoryHandler;
import appeng.util.IterationCounter;
import codechicken.nei.SearchField;
import codechicken.nei.SearchTokenParser;
import codechicken.nei.api.ItemFilter;
@@ -56,7 +63,10 @@ public class NEISearchFilter implements SearchTokenParser.ISearchParserProvider
if (inventory instanceof final IFluidCellInventoryHandler handler) {
final IFluidCellInventory cellInventory = handler.getCellInv();
if (cellInventory != null) {
for (IAEFluidStack fluid : cellInventory.getContents()) {
final ArrayList<IAEFluidStack> out = new ArrayList<>();
handler.getPartitionInv().forEach(out::add);
out.addAll(cellInventory.getContents());
for (IAEFluidStack fluid : out) {
boolean result = pattern.matcher(fluid.getFluidStack().getLocalizedName().toLowerCase())
.find();
if (result) return true;
@@ -65,6 +75,25 @@ public class NEISearchFilter implements SearchTokenParser.ISearchParserProvider
}
}
}
if (itemStack.getItem() instanceof IStorageCell) {
final IMEInventoryHandler<?> inventory = AEApi.instance().registries().cell()
.getCellInventory(itemStack, null, StorageChannel.ITEMS);
if (inventory instanceof final CellInventoryHandler handler) {
final ICellInventory cellInventory = handler.getCellInv();
if (cellInventory != null) {
final IItemList<IAEItemStack> out = AEApi.instance().storage().createItemFilterList();
for (IAEItemStack item : handler.getPartitionList().getItems())
out.add(item);
cellInventory.getAvailableItems(out, IterationCounter.fetchNewId());
for ( IAEItemStack item : out) {
boolean result = pattern.matcher(item.getItemStack().getDisplayName().toLowerCase())
.find();
if (result) return true;
}
}
}
}
return false;
}
@@ -26,6 +26,7 @@ import appeng.container.ContainerOpenContext;
import appeng.container.implementations.ContainerCraftAmount;
import appeng.container.implementations.ContainerPatternItemRenamer;
import appeng.helpers.InventoryAction;
import appeng.tile.networking.TileCableBus;
import appeng.util.item.AEItemStack;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
@@ -42,7 +43,7 @@ public class CPacketInventoryAction implements IMessage {
public CPacketInventoryAction() {}
public CPacketInventoryAction(final InventoryAction action, final int slot, final int id) {
public CPacketInventoryAction(final InventoryAction action, final int slot, final long id) {
this.action = action;
this.slot = slot;
this.id = id;
@@ -50,7 +51,7 @@ public class CPacketInventoryAction implements IMessage {
this.isEmpty = true;
}
public CPacketInventoryAction(final InventoryAction action, final int slot, final int id, IAEItemStack stack) {
public CPacketInventoryAction(final InventoryAction action, final int slot, final long id, IAEItemStack stack) {
this.action = action;
this.slot = slot;
this.id = id;
@@ -122,6 +123,9 @@ public class CPacketInventoryAction implements IMessage {
if (baseContainer.getTargetStack() != null) {
cca.getCraftingItem().putStack(baseContainer.getTargetStack().getItemStack());
cca.setItemToCraft(baseContainer.getTargetStack());
if (message.id > 0) {
cca.setInitialCraftAmount(message.id);
}
}
cca.detectAndSendChanges();
}
@@ -131,12 +135,21 @@ public class CPacketInventoryAction implements IMessage {
if (context != null && message.stack != null) {
final TileEntity te = context.getTile();
if (te != null) {
InventoryHandler.openGui(
if (te instanceof TileCableBus) {
InventoryHandler.openGui(
sender,
te.getWorldObj(),
new BlockPos(te),
Objects.requireNonNull(baseContainer.getOpenContext().getSide()),
GuiType.PATTERN_VALUE_SET);
} else {
InventoryHandler.openGui(
sender,
te.getWorldObj(),
new BlockPos(te),
Objects.requireNonNull(baseContainer.getOpenContext().getSide()),
GuiType.PATTERN_VALUE_SET_TILE);
}
} else if (target instanceof IWirelessTerminal wt) {
InventoryHandler.openGui(
sender,
@@ -1,16 +1,9 @@
package com.glodblock.github.network;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.entity.player.EntityPlayerMP;
import com.glodblock.github.client.gui.container.ContainerLevelMaintainer;
import com.glodblock.github.common.tile.TileLevelMaintainer;
import appeng.api.storage.data.IAEItemStack;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
@@ -19,28 +12,18 @@ import io.netty.buffer.ByteBuf;
public class CPacketLevelMaintainer implements IMessage {
public enum Action {
Refresh,
Quantity,
Batch,
Enable,
Disable
Disable,
}
private Action action;
private long size;
private int slotIndex;
public CPacketLevelMaintainer() {
this.action = Action.Refresh;
this.slotIndex = 0;
this.size = 0;
}
public CPacketLevelMaintainer(Action action) {
this.action = action;
this.slotIndex = 0;
this.size = 0;
}
@SuppressWarnings("unused")
public CPacketLevelMaintainer() {}
public CPacketLevelMaintainer(Action action, int slotIndex) {
this.action = action;
@@ -70,43 +53,17 @@ public class CPacketLevelMaintainer implements IMessage {
public static class Handler implements IMessageHandler<CPacketLevelMaintainer, IMessage> {
private List<IAEItemStack> refresh(ContainerLevelMaintainer cca) {
List<IAEItemStack> toSend = new ArrayList<>(TileLevelMaintainer.REQ_COUNT);
for (int i = 0; i < TileLevelMaintainer.REQ_COUNT; i++) {
IAEItemStack ias = cca.getTile().requests.getAEItemStack(i);
if (ias != null) {
toSend.add(ias);
}
}
return toSend;
}
@Nullable
@Override
public IMessage onMessage(CPacketLevelMaintainer message, MessageContext ctx) {
if (ctx.getServerHandler().playerEntity.openContainer instanceof final ContainerLevelMaintainer clm) {
EntityPlayerMP player = ctx.getServerHandler().playerEntity;
List<IAEItemStack> toSend = switch (message.action) {
case Quantity -> {
clm.getTile().updateQuantity(message.slotIndex, message.size);
yield this.refresh(clm);
}
case Batch -> {
clm.getTile().updateBatchSize(message.slotIndex, message.size);
yield this.refresh(clm);
}
case Enable -> {
clm.getTile().updateStatus(message.slotIndex, false);
yield this.refresh(clm);
}
case Disable -> {
clm.getTile().updateStatus(message.slotIndex, true);
yield this.refresh(clm);
}
case Refresh -> this.refresh(clm);
};
SPacketMEUpdateBuffer.scheduleItemUpdate(player, toSend);
switch (message.action) {
case Quantity -> clm.getTile().updateQuantity(message.slotIndex, message.size);
case Batch -> clm.getTile().updateBatchSize(message.slotIndex, message.size);
case Enable -> clm.getTile().updateStatus(message.slotIndex, false);
case Disable -> clm.getTile().updateStatus(message.slotIndex, true);
}
clm.updateGui();
}
return null;
}
@@ -9,6 +9,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.fluids.FluidStack;
import com.glodblock.github.client.gui.container.ContainerPatternValueAmount;
import com.glodblock.github.client.gui.container.ContainerSuperStockReplenisher;
import com.glodblock.github.client.gui.container.base.FCContainerEncodeTerminal;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.inventory.InventoryHandler;
@@ -92,7 +93,8 @@ public class CPacketPatternValueSet implements IMessage {
Objects.requireNonNull(context.getSide()),
message.originGui);
}
if (player.openContainer instanceof FCContainerEncodeTerminal) {
if (player.openContainer instanceof FCContainerEncodeTerminal
|| player.openContainer instanceof ContainerSuperStockReplenisher) {
Slot slot = player.openContainer.getSlot(message.valueIndex);
if (slot instanceof SlotFake) {
ItemStack stack = slot.getStack().copy();
@@ -67,7 +67,7 @@ public class CPacketValueConfig implements IMessage {
player.addChatMessage(
new ChatComponentText(
StatCollector.translateToLocal(
!Util.isRestock(wirelessTerm)
Util.isRestock(wirelessTerm)
? NameConst.TT_ULTRA_TERMINAL_RESTOCK_ON
: NameConst.TT_ULTRA_TERMINAL_RESTOCK_OFF)));
} else {
@@ -0,0 +1,122 @@
package com.glodblock.github.network;
import static com.glodblock.github.common.tile.TileLevelMaintainer.REQ_COUNT;
import static com.glodblock.github.common.tile.TileLevelMaintainer.RequestInfo;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import com.glodblock.github.api.registries.LevelState;
import com.glodblock.github.client.gui.GuiLevelMaintainer;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
public class SPacketLevelMaintainerGuiUpdate implements IMessage {
private Info[] infoList;
private boolean onlyState;
@SuppressWarnings("unused")
public SPacketLevelMaintainerGuiUpdate() {}
public SPacketLevelMaintainerGuiUpdate(RequestInfo[] requests, boolean onlyState) {
this.infoList = new Info[REQ_COUNT];
this.onlyState = onlyState;
for (int i = 0; i < REQ_COUNT; i++) {
if (requests[i] == null) {
this.infoList[i] = null;
} else {
this.infoList[i] = new Info(
requests[i].getQuantity(),
requests[i].getBatchSize(),
requests[i].isEnable(),
requests[i].getState());
}
}
}
@Override
public void fromBytes(ByteBuf buf) {
this.infoList = new Info[REQ_COUNT];
this.onlyState = buf.readBoolean();
for (int i = 0; i < REQ_COUNT; i++) {
if (buf.readBoolean()) {
if (this.onlyState) {
this.infoList[i] = new Info(LevelState.values()[buf.readInt()]);
} else {
this.infoList[i] = new Info(
buf.readLong(),
buf.readLong(),
buf.readBoolean(),
LevelState.values()[buf.readInt()]);
}
} else {
this.infoList[i] = null;
}
}
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeBoolean(this.onlyState);
for (Info info : this.infoList) {
buf.writeBoolean(info != null);
if (info == null) continue;
if (!this.onlyState) {
buf.writeLong(info.quantity);
buf.writeLong(info.batchSize);
buf.writeBoolean(info.enable);
}
buf.writeInt(info.state.ordinal());
}
}
private static class Info {
long quantity;
long batchSize;
boolean enable;
LevelState state;
Info(long quantity, long batchSize, boolean enable, LevelState state) {
this.quantity = quantity;
this.batchSize = batchSize;
this.enable = enable;
this.state = state;
}
Info(LevelState state) {
this.quantity = 0;
this.batchSize = 0;
this.enable = false;
this.state = state;
}
}
public static class Handler implements IMessageHandler<SPacketLevelMaintainerGuiUpdate, IMessage> {
@Override
public IMessage onMessage(SPacketLevelMaintainerGuiUpdate message, MessageContext ctx) {
final GuiScreen gs = Minecraft.getMinecraft().currentScreen;
if (gs instanceof GuiLevelMaintainer gui) {
for (int i = 0; i < REQ_COUNT; i++) {
Info info = message.infoList[i];
if (info == null) continue;
if (message.onlyState) {
gui.updateComponent(i, info.state);
} else {
gui.updateComponent(i, info.quantity, info.batchSize, info.enable, info.state);
}
}
}
return null;
}
}
}
@@ -1,22 +1,17 @@
package com.glodblock.github.network;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.common.util.ForgeDirection;
import org.jetbrains.annotations.Nullable;
import com.glodblock.github.api.registries.LevelItemInfo;
import com.glodblock.github.api.registries.LevelState;
import com.glodblock.github.client.gui.GuiLevelTerminal;
import appeng.core.AEConfig;
@@ -27,58 +22,28 @@ import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.buffer.Unpooled;
/**
* Packet used for level terminal updates. Packet allows the server to send an array of command packets, which are then
* processed in order. This allows for chaining commands to produce the desired update.
*/
public class SPacketLevelTerminalUpdate implements IMessage {
public static final int CLEAR_ALL_BIT = 1;
public static final int DISCONNECT_BIT = 2;
private final List<PacketEntry> commands = new ArrayList<>();
private int statusFlags;
public SPacketLevelTerminalUpdate() {}
@Override
public void fromBytes(ByteBuf buf) {
this.statusFlags = buf.readByte();
int numEntries = buf.readInt();
int entryNum = buf.readInt();
for (int i = 0; i < numEntries; ++i) {
try {
PacketType type = PacketType.values()[buf.readByte()];
for (int i = 0; i < entryNum; i++) {
PacketType type = PacketType.values()[buf.readByte()];
switch (type) {
case ADD -> this.commands.add(new PacketAdd(buf));
case REMOVE -> this.commands.add(new PacketRemove(buf));
case OVERWRITE -> this.commands.add(new PacketOverwrite(buf));
case RENAME -> this.commands.add(new PacketRename(buf));
default -> throw new IOException("Unknown packet type received of index " + type);
}
} catch (Exception e) {
if (AEConfig.instance.isFeatureEnabled(AEFeature.PacketLogging)) {
AELog.info(
"Corrupted packet commands: (" + i
+ ") of ("
+ numEntries
+ ") -> "
+ this.commands.size()
+ " : "
+ this.commands.stream().map(packetEntry -> packetEntry.getClass().getSimpleName())
.collect(Collectors.groupingBy(String::new, Collectors.counting())));
if (AEConfig.instance.isFeatureEnabled(AEFeature.DebugLogging)) {
AELog.info(" <- Parsed content: " + this.commands);
}
}
AELog.debug(e);
return;
switch (type) {
case ADD -> this.commands.add(new PacketAdd(buf));
case REMOVE -> this.commands.add(new PacketRemove(buf));
case RENAME -> this.commands.add(new PacketRename(buf));
case DISCONNECT -> this.commands.add(new PacketDisconnect(buf));
case OVERWRITE_SLOT -> this.commands.add(new PacketOverwriteSlot(buf));
case OVERWITE_ALL_SLOT -> this.commands.add(new PacketOverwirteAllSlot(buf));
}
}
if (AEConfig.instance.isFeatureEnabled(AEFeature.PacketLogging)) {
AELog.info(
" <- Received commands " + this.commands.size()
@@ -88,80 +53,49 @@ public class SPacketLevelTerminalUpdate implements IMessage {
}
}
@Override
public void toBytes(ByteBuf buf) {
try {
if (AEConfig.instance.isFeatureEnabled(AEFeature.PacketLogging)) {
AELog.info(
" <- Sent commands " + this.commands.size()
+ " : "
+ this.commands.stream().map(packetEntry -> packetEntry.getClass().getSimpleName())
.collect(Collectors.groupingBy(String::new, Collectors.counting())));
if (AEConfig.instance.isFeatureEnabled(AEFeature.DebugLogging)) {
AELog.info(" -> Sent commands: " + this.commands);
}
}
buf.writeInt(commands.size());
for (PacketEntry entry : this.commands) {
buf.writeByte(entry.getType().ordinal());
entry.write(buf);
}
buf.writeByte(statusFlags);
buf.writeInt(commands.size());
for (PacketEntry entry : commands) {
entry.write(buf);
if (AEConfig.instance.isFeatureEnabled(AEFeature.PacketLogging)) {
AELog.info(
" <- Sent commands " + this.commands.size()
+ " : "
+ this.commands.stream().map(packetEntry -> packetEntry.getClass().getSimpleName())
.collect(Collectors.groupingBy(String::new, Collectors.counting())));
if (AEConfig.instance.isFeatureEnabled(AEFeature.DebugLogging)) {
AELog.info(" -> Sent commands: " + this.commands);
}
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
/**
* Remove all entries on the terminal. This is done BEFORE any entries are processed, so you can set this to clear
* old entries, and add new ones after in one packet.
*/
public void setClear() {
statusFlags |= CLEAR_ALL_BIT;
public void addNewEntry(long id, int x, int y, int z, int dim, int side, int rows, int rowSize, String name,
LevelItemInfo[] infolist) {
this.commands.add(new PacketAdd(id, x, y, z, dim, side, rows, rowSize, name, infolist));
}
/**
* The terminal disconnected. Entries are still processed, but indicates for the GUI to darken/turn off the
* terminal. No further updates will arrive until the terminal reconnects.
*/
public void setDisconnect() {
this.statusFlags |= DISCONNECT_BIT;
public void addRemoveEntry(long id) {
this.commands.add(new PacketRemove(id));
}
/**
* Adds a new entry. Fill out the rest of the command using the {@link PacketAdd#setItems(int, int, NBTTagList)} and
* {@link PacketAdd#setLocation(int, int, int, int, int)}.
*
* @return the packet, which needs to have information filled out.
*/
public PacketAdd addNewEntry(long id, String name, boolean online) {
PacketAdd packet = new PacketAdd(id, name, online);
commands.add(packet);
return packet;
public void addRenameEntry(long id, String newName) {
this.commands.add(new PacketRename(id, newName));
}
/**
* Remove the entry with the id from the terminal.
*/
public void addRemovalEntry(long id) {
commands.add(new PacketRemove(id));
public void addDisconnectEntry() {
this.commands.add(new PacketDisconnect());
}
/**
* Rename the entry
*/
public void addRenamedEntry(long id, String newName) {
commands.add(new PacketRename(id, newName));
public void addOverwriteSlotEntry(long id, int index, LevelItemInfo info) {
this.commands.add(new PacketOverwriteSlot(id, index, info));
}
/**
* Overwrite the entry with new items or new status
*/
public PacketOverwrite addOverwriteEntry(long id) {
PacketOverwrite packet = new PacketOverwrite(id);
commands.add(packet);
return packet;
public void addOverwriteAllSlotEntry(long id, LevelItemInfo[] info) {
this.commands.add(new PacketOverwirteAllSlot(id, info));
}
public static class Handler implements IMessageHandler<SPacketLevelTerminalUpdate, IMessage> {
@@ -172,23 +106,22 @@ public class SPacketLevelTerminalUpdate implements IMessage {
final GuiScreen gs = Minecraft.getMinecraft().currentScreen;
if (gs instanceof GuiLevelTerminal levelTerminal) {
levelTerminal.postUpdate(message.commands, message.statusFlags);
levelTerminal.receivePackets(message.commands);
}
return null;
}
}
enum PacketType {
protected enum PacketType {
ADD,
REMOVE,
OVERWRITE,
RENAME,
DISCONNECT,
OVERWRITE_SLOT,
OVERWITE_ALL_SLOT,
}
/**
* A packet for updating an entry.
*/
public abstract static class PacketEntry {
public final long entryId;
@@ -197,181 +130,87 @@ public class SPacketLevelTerminalUpdate implements IMessage {
this.entryId = entryId;
}
protected PacketEntry(ByteBuf buf) throws IOException {
public PacketEntry(ByteBuf buf) {
this.entryId = buf.readLong();
read(buf);
}
/**
* Needs to write the packet id.
*/
protected abstract void write(ByteBuf buf) throws IOException;
protected abstract PacketType getType();
/**
* Reading the entry id is not needed.
*/
protected abstract void read(ByteBuf buf) throws IOException;
protected void write(ByteBuf buf) {
buf.writeLong(this.entryId);
}
}
/**
* A command for sending a new entry.
*/
public static class PacketAdd extends PacketEntry {
public String name;
public int x, y, z, dim, side;
public int rows, rowSize;
public boolean online;
public ItemStack selfItemStack;
public ItemStack displayItemStack;
public NBTTagList items;
public String name;
public LevelItemInfo[] infolist;
PacketAdd(long id, String name, boolean online) {
PacketAdd(long id, int x, int y, int z, int dim, int side, int rows, int rowSize, String name,
LevelItemInfo[] infolist) {
super(id);
this.name = name;
this.online = online;
}
PacketAdd(ByteBuf buf) throws IOException {
super(buf);
}
public PacketAdd setLocation(int x, int y, int z, int dim, int side) {
this.x = x;
this.y = y;
this.z = z;
this.dim = dim;
this.side = side;
return this;
}
public PacketAdd setItems(int rows, int rowSize, NBTTagList items) {
this.rows = rows;
this.rowSize = rowSize;
this.items = items;
return this;
this.name = name;
this.infolist = infolist;
}
public PacketAdd setViewItemStack(ItemStack selfItemStack, ItemStack displayItemStack) {
this.selfItemStack = selfItemStack;
this.displayItemStack = displayItemStack;
return this;
}
@Override
protected void write(ByteBuf buf) throws IOException {
buf.writeByte(PacketType.ADD.ordinal());
buf.writeLong(entryId);
ByteBufUtils.writeUTF8String(buf, this.name);
buf.writeInt(x);
buf.writeInt(y);
buf.writeInt(z);
buf.writeInt(dim);
buf.writeByte(side);
buf.writeInt(rows);
buf.writeInt(rowSize);
ByteBuf tempBuf = Unpooled.directBuffer(256);
try {
try (ByteBufOutputStream stream = new ByteBufOutputStream(tempBuf)) {
NBTTagCompound wrapper = new NBTTagCompound();
if (selfItemStack != null) {
wrapper.setTag("self", selfItemStack.writeToNBT(new NBTTagCompound()));
}
if (displayItemStack != null) {
wrapper.setTag("display", displayItemStack.writeToNBT(new NBTTagCompound()));
}
wrapper.setTag("data", items);
CompressedStreamTools.writeCompressed(wrapper, stream);
}
buf.writeInt(tempBuf.readableBytes());
buf.writeBytes(tempBuf);
} finally {
tempBuf.release();
}
}
@Override
protected void read(ByteBuf buf) throws IOException {
this.name = ByteBufUtils.readUTF8String(buf);
public PacketAdd(ByteBuf buf) {
super(buf);
this.x = buf.readInt();
this.y = buf.readInt();
this.z = buf.readInt();
this.dim = buf.readInt();
this.side = buf.readByte();
this.side = buf.readInt();
this.rows = buf.readInt();
this.rowSize = buf.readInt();
int payloadSize = buf.readInt();
try (ByteBufInputStream stream = new ByteBufInputStream(buf, payloadSize)) {
NBTTagCompound payload = CompressedStreamTools.readCompressed(stream);
int available = stream.available();
if (available > 0) {
byte[] left = new byte[available];
int read = stream.read(left);
if (AEConfig.instance.isFeatureEnabled(AEFeature.PacketLogging)) {
AELog.info(
"Unread bytes detected (" + read
+ "): "
+ Arrays.toString(left)
+ " at "
+ dim
+ "#("
+ x
+ ":"
+ y
+ ":"
+ z
+ ")@"
+ ForgeDirection.getOrientation(side));
}
}
if (payload.hasKey("self", NBT.TAG_COMPOUND)) {
this.selfItemStack = ItemStack.loadItemStackFromNBT(payload.getCompoundTag("self"));
}
if (payload.hasKey("display", NBT.TAG_COMPOUND)) {
this.displayItemStack = ItemStack.loadItemStackFromNBT(payload.getCompoundTag("display"));
}
this.items = payload.getTagList("data", NBT.TAG_COMPOUND);
this.name = ByteBufUtils.readUTF8String(buf);
int infoSize = buf.readInt();
infolist = new LevelItemInfo[infoSize];
for (int i = 0; i < infoSize; i++) {
if (!buf.readBoolean()) continue;
ItemStack stack = ByteBufUtils.readItemStack(buf);
long quantity = buf.readLong();
long batchSize = buf.readLong();
LevelState state = LevelState.values()[buf.readInt()];
infolist[i] = new LevelItemInfo(stack, quantity, batchSize, state);
}
}
@Override
public String toString() {
return "PacketAdd{" + "name='"
+ name
+ '\''
+ ", x="
+ x
+ ", y="
+ y
+ ", z="
+ z
+ ", dim="
+ dim
+ ", side="
+ side
+ ", rows="
+ rows
+ ", rowSize="
+ rowSize
+ ", online="
+ online
+ ", selfItemStack="
+ selfItemStack
+ ", displayItemStack="
+ displayItemStack
+ ", items="
+ items
+ ", entryId="
+ entryId
+ '}';
protected PacketType getType() {
return PacketType.ADD;
}
@Override
protected void write(ByteBuf buf) {
super.write(buf);
buf.writeInt(this.x);
buf.writeInt(this.y);
buf.writeInt(this.z);
buf.writeInt(this.dim);
buf.writeInt(this.side);
buf.writeInt(this.rows);
buf.writeInt(this.rowSize);
ByteBufUtils.writeUTF8String(buf, this.name);
buf.writeInt(this.infolist.length);
for (int i = 0; i < this.infolist.length; i++) {
LevelItemInfo info = this.infolist[i];
buf.writeBoolean(info != null);
if (info == null) continue;
// System.out.println("Writing info: " + info.stack != null);
ByteBufUtils.writeItemStack(buf, info.stack);
buf.writeLong(info.quantity);
buf.writeLong(info.batchSize);
buf.writeInt(info.state.ordinal());
}
}
}
@@ -381,205 +220,147 @@ public class SPacketLevelTerminalUpdate implements IMessage {
super(id);
}
PacketRemove(ByteBuf buf) throws IOException {
PacketRemove(ByteBuf buf) {
super(buf);
}
@Override
protected PacketType getType() {
return PacketType.REMOVE;
}
@Override
protected void write(ByteBuf buf) {
buf.writeByte(PacketType.REMOVE.ordinal());
buf.writeLong(entryId);
}
@Override
protected void read(ByteBuf buf) {}
@Override
public String toString() {
return "PacketRemove{" + "entryId=" + entryId + '}';
super.write(buf);
}
}
/**
* Overwrite online status or inventory of the entry.
*/
public static class PacketOverwrite extends PacketEntry {
public static final int ONLINE_BIT = 1;
public static final int ONLINE_VALID = 1 << 1;
public static final int ITEMS_VALID = 1 << 2;
public static final int ALL_ITEM_UPDATE_BIT = 1 << 3;
public boolean onlineValid;
public boolean online;
public boolean itemsValid;
public boolean allItemUpdate;
public int[] validIndices;
public NBTTagList items;
protected PacketOverwrite(long id) {
super(id);
}
protected PacketOverwrite(ByteBuf buf) throws IOException {
super(buf);
}
public PacketOverwrite setOnline(boolean online) {
this.onlineValid = true;
this.online = online;
return this;
}
public PacketOverwrite setItems(int[] validIndices, NBTTagList items) {
this.itemsValid = true;
this.allItemUpdate = validIndices == null || validIndices.length == 0;
this.validIndices = validIndices;
this.items = items;
return this;
}
public PacketOverwrite setItems(int newSize, NBTTagList items) {
this.itemsValid = true;
this.allItemUpdate = true;
this.validIndices = new int[newSize];
this.items = items;
return this;
}
@Override
protected void write(ByteBuf buf) throws IOException {
buf.writeByte(PacketType.OVERWRITE.ordinal());
buf.writeLong(entryId);
int flags = 0;
if (onlineValid) {
flags |= ONLINE_VALID;
flags |= online ? ONLINE_BIT : 0;
}
if (itemsValid) {
flags |= ITEMS_VALID;
if (allItemUpdate) {
flags |= ALL_ITEM_UPDATE_BIT;
buf.writeByte(flags);
buf.writeInt(validIndices.length);
} else {
buf.writeByte(flags);
buf.writeInt(validIndices.length);
for (int validIndex : validIndices) {
buf.writeInt(validIndex);
}
}
ByteBuf tempBuf = Unpooled.directBuffer(256);
try {
try (ByteBufOutputStream stream = new ByteBufOutputStream(tempBuf)) {
NBTTagCompound wrapper = new NBTTagCompound();
wrapper.setTag("data", items);
CompressedStreamTools.writeCompressed(wrapper, stream);
}
buf.writeInt(tempBuf.readableBytes());
buf.writeBytes(tempBuf);
} finally {
tempBuf.release();
}
} else {
buf.writeByte(flags);
}
}
@Override
protected void read(ByteBuf buf) throws IOException {
int flags = buf.readByte();
/* Decide whether to use online flag or not */
if ((flags & ONLINE_VALID) == ONLINE_VALID) {
this.onlineValid = true;
this.online = (flags & ONLINE_BIT) == ONLINE_BIT;
}
/* Decide whether to read item list or not */
if ((flags & ITEMS_VALID) == ITEMS_VALID) {
this.itemsValid = true;
if ((flags & ALL_ITEM_UPDATE_BIT) == ALL_ITEM_UPDATE_BIT) {
this.allItemUpdate = true;
int numItems = buf.readInt();
this.validIndices = new int[numItems];
} else {
int numItems = buf.readInt();
this.validIndices = new int[numItems];
for (int i = 0; i < numItems; ++i) {
this.validIndices[i] = buf.readInt();
}
}
int payloadSize = buf.readInt();
try (ByteBufInputStream stream = new ByteBufInputStream(buf, payloadSize)) {
this.items = CompressedStreamTools.readCompressed(stream).getTagList("data", NBT.TAG_COMPOUND);
int available = stream.available();
if (available > 0) {
byte[] left = new byte[available];
int read = stream.read(left);
if (AEConfig.instance.isFeatureEnabled(AEFeature.PacketLogging)) {
AELog.info("Unread bytes detected (" + read + "): " + Arrays.toString(left));
}
}
}
}
}
@Override
public String toString() {
return "PacketOverwrite{" + "onlineValid="
+ onlineValid
+ ", online="
+ online
+ ", itemsValid="
+ itemsValid
+ ", allItemUpdate="
+ allItemUpdate
+ ", validIndices="
+ Arrays.toString(validIndices)
+ ", items="
+ items
+ ", entryId="
+ entryId
+ '}';
}
}
/**
* Rename the entry.
*/
public static class PacketRename extends PacketEntry {
public String newName;
protected PacketRename(long id, String newName) {
PacketRename(long id, String newName) {
super(id);
this.newName = newName;
}
protected PacketRename(ByteBuf buf) throws IOException {
PacketRename(ByteBuf buf) {
super(buf);
this.newName = ByteBufUtils.readUTF8String(buf);
}
@Override
protected PacketType getType() {
return PacketType.RENAME;
}
@Override
protected void write(ByteBuf buf) {
buf.writeByte(PacketType.RENAME.ordinal());
buf.writeLong(entryId);
ByteBufUtils.writeUTF8String(buf, newName);
super.write(buf);
ByteBufUtils.writeUTF8String(buf, this.newName);
}
}
public static class PacketDisconnect extends PacketEntry {
PacketDisconnect() {
super(0); // Ignored id
}
PacketDisconnect(ByteBuf buf) {
super(buf);
}
@Override
protected void read(ByteBuf buf) {
newName = ByteBufUtils.readUTF8String(buf);
protected PacketType getType() {
return PacketType.DISCONNECT;
}
}
public static class PacketOverwriteSlot extends PacketEntry {
public int index;
public LevelItemInfo info;
PacketOverwriteSlot(long id, int index, LevelItemInfo info) {
super(id);
this.index = index;
this.info = info;
}
PacketOverwriteSlot(ByteBuf buf) {
super(buf);
this.index = buf.readInt();
if (buf.readBoolean()) {
this.info = new LevelItemInfo(
ByteBufUtils.readItemStack(buf),
buf.readLong(),
buf.readLong(),
LevelState.values()[buf.readInt()]);
} else {
this.info = null;
}
}
@Override
public String toString() {
return "PacketRename{" + "newName='" + newName + '\'' + ", entryId=" + entryId + '}';
protected PacketType getType() {
return PacketType.OVERWRITE_SLOT;
}
@Override
protected void write(ByteBuf buf) {
super.write(buf);
buf.writeInt(index);
buf.writeBoolean(info != null);
ByteBufUtils.writeItemStack(buf, info.stack);
buf.writeLong(info.quantity);
buf.writeLong(info.batchSize);
buf.writeInt(info.state.ordinal());
}
}
public static class PacketOverwirteAllSlot extends PacketEntry {
public LevelItemInfo[] infoList;
PacketOverwirteAllSlot(long id, LevelItemInfo[] info) {
super(id);
this.infoList = info;
}
PacketOverwirteAllSlot(ByteBuf buf) {
super(buf);
int infoSize = buf.readInt();
this.infoList = new LevelItemInfo[infoSize];
for (int i = 0; i < infoSize; i++) {
if (!buf.readBoolean()) continue;
ItemStack stack = ByteBufUtils.readItemStack(buf);
long quantity = buf.readLong();
long batchSize = buf.readLong();
LevelState state = LevelState.values()[buf.readInt()];
this.infoList[i] = new LevelItemInfo(stack, quantity, batchSize, state);
}
}
@Override
protected PacketType getType() {
return PacketType.OVERWITE_ALL_SLOT;
}
@Override
protected void write(ByteBuf buf) {
super.write(buf);
buf.writeInt(this.infoList.length);
for (int i = 0; i < this.infoList.length; i++) {
LevelItemInfo info = this.infoList[i];
buf.writeBoolean(info != null);
if (info == null) continue;
buf.writeInt(i);
ByteBufUtils.writeItemStack(buf, info.stack);
buf.writeLong(info.quantity);
buf.writeLong(info.batchSize);
buf.writeInt(info.state.ordinal());
}
}
}
}
@@ -9,7 +9,6 @@ import net.minecraft.client.gui.GuiScreen;
import com.glodblock.github.client.gui.GuiFluidCraftConfirm;
import com.glodblock.github.client.gui.GuiItemMonitor;
import com.glodblock.github.client.gui.GuiLevelMaintainer;
import appeng.api.storage.data.IAEItemStack;
import appeng.util.item.AEItemStack;
@@ -97,8 +96,6 @@ public class SPacketMEItemInvUpdate implements IMessage {
((GuiItemMonitor) gs).postUpdate(message.list, message.resort);
} else if (gs instanceof GuiFluidCraftConfirm) {
((GuiFluidCraftConfirm) gs).postUpdate(message.list, message.ref);
} else if (gs instanceof GuiLevelMaintainer) {
((GuiLevelMaintainer) gs).postUpdate(message.list);
}
return null;
}
@@ -95,7 +95,6 @@ public class SPacketPatternItemRenamer implements IMessage {
Slot slot = player.openContainer.getSlot(message.valueIndex);
if (slot != null && slot.getHasStack()) {
ItemStack nextStack = slot.getStack().copy();
nextStack.setRepairCost(2);
nextStack.setStackDisplayName(message.name);
slot.putStack(nextStack);
}
@@ -0,0 +1,59 @@
package com.glodblock.github.network;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import com.glodblock.github.client.gui.GuiSuperStockReplenisher;
import com.glodblock.github.util.Util;
import appeng.api.storage.data.IAEStack;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
public class SPacketSuperStockReplenisherUpdate implements IMessage {
private Map<Integer, IAEStack<?>> list;
public SPacketSuperStockReplenisherUpdate() {}
public SPacketSuperStockReplenisherUpdate(Map<Integer, IAEStack<?>> data) {
this.list = data;
}
@Override
public void fromBytes(ByteBuf buf) {
this.list = new HashMap<>();
try {
Util.readAEStackMapFromBuf(this.list, buf);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void toBytes(ByteBuf buf) {
try {
Util.writeAEStackMapToBuf(this.list, buf);
} catch (IOException e) {
e.printStackTrace();
}
}
public static class Handler implements IMessageHandler<SPacketSuperStockReplenisherUpdate, IMessage> {
@Override
public IMessage onMessage(SPacketSuperStockReplenisherUpdate message, MessageContext ctx) {
final GuiScreen gs = Minecraft.getMinecraft().currentScreen;
if (gs instanceof GuiSuperStockReplenisher gss) {
gss.update(message.list);
}
return null;
}
}
}
@@ -70,10 +70,7 @@ public class CommonProxy {
.getFilter(wirelessTerm, result.getLeft(), gridNode, player);
if (inv.isPassFilter(stack)) {
if (inv.doInject(
AEApi.instance().storage().createItemStack(stack),
itemEntity,
world)) {
if (inv.doInject(AEApi.instance().storage().createItemStack(stack), itemEntity)) {
itemEntity.setDead();
e.setCanceled(true);
}
@@ -94,7 +91,7 @@ public class CommonProxy {
public void init(FMLInitializationEvent event) {
this.registerMovables();
FMLCommonHandler.instance().bus().register(SPacketMEUpdateBuffer.class);
FMLCommonHandler.instance().bus().register(new SPacketMEUpdateBuffer());
if (ModAndClassUtil.ThE) {
AspectUtil.init();
}
@@ -120,6 +117,9 @@ public class CommonProxy {
Upgrades.LOCK_CRAFTING.registerItem(new ItemStack(ItemAndBlockHolder.FLUID_INTERFACE), 1);
Upgrades.LOCK_CRAFTING.registerItem(new ItemStack(ItemAndBlockHolder.INTERFACE), 1);
Upgrades.LOCK_CRAFTING.registerItem(new ItemStack(ItemAndBlockHolder.FLUID_INTERFACE_P2P), 1);
Upgrades.FUZZY.registerItem(new ItemStack(ItemAndBlockHolder.FLUID_INTERFACE), 3);
Upgrades.FUZZY.registerItem(new ItemStack(ItemAndBlockHolder.INTERFACE), 3);
Upgrades.FUZZY.registerItem(new ItemStack(ItemAndBlockHolder.FLUID_INTERFACE_P2P), 3);
Upgrades.CAPACITY.registerItem(new ItemStack(ItemAndBlockHolder.FLUID_STORAGE_BUS), 5);
Upgrades.INVERTER.registerItem(new ItemStack(ItemAndBlockHolder.FLUID_STORAGE_BUS), 1);
Upgrades.STICKY.registerItem(new ItemStack(ItemAndBlockHolder.FLUID_STORAGE_BUS), 1);
@@ -9,7 +9,6 @@ import appeng.core.AEConfig;
import appeng.core.localization.ButtonToolTips;
import appeng.core.localization.GuiText;
import cpw.mods.fml.common.Loader;
import gregtech.api.enums.Mods;
public final class ModAndClassUtil {
@@ -150,6 +149,6 @@ public final class ModAndClassUtil {
if (Loader.isModLoaded("Waila")) WAILA = true;
if (Loader.isModLoaded("Avaritia")) AVARITIA = true;
if (Loader.isModLoaded("hodgepodge")) HODGEPODGE = true;
if (Loader.isModLoaded(Mods.Names.NEW_HORIZONS_CORE_MOD)) NEW_HORIZONS_CORE_MOD = true;
if (Loader.isModLoaded("dreamcraft")) NEW_HORIZONS_CORE_MOD = true;
}
}
@@ -21,6 +21,7 @@ public class NameConst {
public static final String BLOCK_OC_PATTERN_EDITOR = "oc_pattern_editor";
public static final String BLOCK_LEVEL_MAINTAINER = "level_maintainer";
public static final String BLOCK_WALRUS = "walrus";
public static final String BLOCK_SUPER_STOCK_REPLENISHER = "super_stock_replenisher";
public static final String ITEM_FLUID_DROP = "fluid_drop";
public static final String ITEM_FLUID_ENCODED_PATTERN = "fluid_encoded_pattern";
public static final String ITEM_PART_FLUID_STORAGE_MONITOR = "part_fluid_storage_monitor";
@@ -92,6 +93,10 @@ public class NameConst {
public static final String TT_LEVEL_MAINTAINER_EXPORT_DESC = TT_LEVEL_MAINTAINER + "export_desc";
public static final String TT_LEVEL_MAINTAINER_ERROR = TT_LEVEL_MAINTAINER + "error";
public static final String TT_LEVEL_MAINTAINER_ERROR_DESC = TT_LEVEL_MAINTAINER + "error_desc";
public static final String TT_LEVEL_MAINTAINER_NOT_FOUND = TT_LEVEL_MAINTAINER + "not_found";
public static final String TT_LEVEL_MAINTAINER_NOT_FOUND_DESC = TT_LEVEL_MAINTAINER + "not_found_desc";
public static final String TT_LEVEL_MAINTAINER_CANT_CRAFT = TT_LEVEL_MAINTAINER + "cant_craft";
public static final String TT_LEVEL_MAINTAINER_CANT_CRAFT_DESC = TT_LEVEL_MAINTAINER + "cant_craft_desc";
public static final String TT_CELL_CONTENTS = TT_KEY + "cell_contents";
public static final String TT_CELL_EMPTY = TT_KEY + "cell_empty";
public static final String TT_CELL_PORTABLE = TT_KEY + "cell_portable";
@@ -27,20 +27,21 @@ public final class RenderUtil {
if (icon == null) {
return;
}
Tessellator.instance.startDrawingQuads();
Tessellator.instance.setNormal(nx, ny, nz);
final Tessellator tess = Tessellator.instance;
tess.startDrawingQuads();
tess.setNormal(nx, ny, nz);
if (nz > 0.0F) {
Tessellator.instance.addVertexWithUV(xStart, yStart, z, icon.getMinU(), icon.getMinV());
Tessellator.instance.addVertexWithUV(xEnd, yStart, z, icon.getMaxU(), icon.getMinV());
Tessellator.instance.addVertexWithUV(xEnd, yEnd, z, icon.getMaxU(), icon.getMaxV());
Tessellator.instance.addVertexWithUV(xStart, yEnd, z, icon.getMinU(), icon.getMaxV());
tess.addVertexWithUV(xStart, yStart, z, icon.getMinU(), icon.getMinV());
tess.addVertexWithUV(xEnd, yStart, z, icon.getMaxU(), icon.getMinV());
tess.addVertexWithUV(xEnd, yEnd, z, icon.getMaxU(), icon.getMaxV());
tess.addVertexWithUV(xStart, yEnd, z, icon.getMinU(), icon.getMaxV());
} else {
Tessellator.instance.addVertexWithUV(xStart, yEnd, z, icon.getMinU(), icon.getMaxV());
Tessellator.instance.addVertexWithUV(xEnd, yEnd, z, icon.getMaxU(), icon.getMaxV());
Tessellator.instance.addVertexWithUV(xEnd, yStart, z, icon.getMaxU(), icon.getMinV());
Tessellator.instance.addVertexWithUV(xStart, yStart, z, icon.getMinU(), icon.getMinV());
tess.addVertexWithUV(xStart, yEnd, z, icon.getMinU(), icon.getMaxV());
tess.addVertexWithUV(xEnd, yEnd, z, icon.getMaxU(), icon.getMaxV());
tess.addVertexWithUV(xEnd, yStart, z, icon.getMaxU(), icon.getMinV());
tess.addVertexWithUV(xStart, yStart, z, icon.getMinU(), icon.getMinV());
}
Tessellator.instance.draw();
tess.draw();
}
public static void renderFluidIntoGui(Gui gui, int x, int y, int width, int height,
@@ -51,6 +51,7 @@ import appeng.api.parts.IPart;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.util.DimensionalCoord;
import appeng.api.util.WorldCoord;
import appeng.container.AEBaseContainer;
@@ -60,6 +61,7 @@ import appeng.tile.networking.TileCableBus;
import appeng.tile.networking.TileWireless;
import appeng.util.Platform;
import appeng.util.item.AEFluidStack;
import appeng.util.item.AEItemStack;
import baubles.api.BaublesApi;
import codechicken.nei.recipe.StackInfo;
import cpw.mods.fml.common.Loader;
@@ -413,6 +415,36 @@ public final class Util {
}
}
public static void writeAEStackMapToBuf(Map<Integer, IAEStack<?>> list, ByteBuf buf) throws IOException {
buf.writeInt(list.size());
for (Map.Entry<Integer, IAEStack<?>> as : list.entrySet()) {
buf.writeInt(as.getKey());
if (as.getValue() == null) buf.writeBoolean(false);
else {
buf.writeBoolean(true);
as.getValue().writeToPacket(buf);
}
}
}
public static void readAEStackMapFromBuf(Map<Integer, IAEStack<?>> list, ByteBuf buf) throws IOException {
int size = buf.readInt();
for (int i = 0; i < size; i++) {
int id = buf.readInt();
boolean isNull = buf.readBoolean();
if (!isNull) list.put(id, null);
else {
IAEStack<?> as;
if (id > 99) {
as = AEItemStack.loadItemStackFromPacket(buf);
} else {
as = AEFluidStack.loadFluidStackFromPacket(buf);
}
list.put(id, as);
}
}
}
public static class GuiHelper {
public enum GuiType {
@@ -0,0 +1,241 @@
item.fluid_drop.name=Tropfen %s
item.fluid_encoded_pattern.name=Kodierte ME-Flüssigkeitsschablone
item.part_fluid_terminal.name=ME-Flüssigkeitskonsole
item.part_fluid_pattern_terminal.name=ME-Flüssigkeitsschablonenkonsole
item.part_fluid_pattern_terminal_ex.name=ME-Flüssigkeitsverarbeitungsschablonenkonsole
item.part_fluid_interface.name=ME-Dualschnittstelle
item.part_fluid_p2p_interface.name=P2P-Tunnel - ME-Dualschnittstelle
item.part_fluid_import.name=ME-Flüssigkeits-Importbus
item.part_fluid_export.name=ME-Flüssigkeits-Exportbus
item.part_fluid_storage_bus.name=ME-Flüssigkeitsspeicherbus
item.part_fluid_level_emitter.name=ME-Flüssigkeitsfüllstandsemitter
item.part_fluid_storage_monitor.name=ME-Flüssigkeitsspeicherkonsole
item.part_fluid_conversion_monitor.name=ME-Flüssigkeitsumwandlungskonsole
item.part_level_terminal.name=ME-Füllstandkonsole
item.portable_fluid_cell.name=Tragbare Flüssigkeitszelle
item.wireless_fluid_terminal.name=Flüssigkeits-Handkonsole
item.wireless_level_terminal.name=Füllstands-Handkonsole
item.wireless_fluid_pattern_terminal.name=Flüssigkeitsschablonen-Handkonsole
item.wireless_interface_terminal.name=Schnittstellen-Handkonsole
item.wireless_ultra_terminal.name=Universelle Handkonsole
item.wireless_ultra_terminal.WIRELESS_CRAFTING_TERMINAL.name=Universelle Handkonsole - Fertigung
item.wireless_ultra_terminal.WIRELESS_FLUID_PATTERN_TERMINAL.name=Universelle Handkonsole - Schablonen
item.wireless_ultra_terminal.WIRELESS_FLUID_TERMINAL.name=Universelle Handkonsole - Flüssigkeiten
item.wireless_ultra_terminal.WIRELESS_LEVEL_TERMINAL.name=Universelle Handkonsole - Füllstände
item.wireless_ultra_terminal.WIRELESS_ESSENTIA_TERMINAL.name=Universelle Handkonsole - Essentia
item.wireless_ultra_terminal.WIRELESS_INTERFACE_TERMINAL.name=Universelle Handkonsole - Schnittstelle
item.wireless_ultra_terminal.WIRELESS_FLUID_PATTERN_TERMINAL_EX.name=Universelle Handkonsole - Fertigungsschablone
item.fluid_packet.name=Flüssigkeitspaket
item.quantum_bridge_card.name=Quantenbrücken-Karte
item.energy_card.name=Energiekarte
item.creative_fluid_storage.name=Kreative ME-Flüssigkeitsspeicherzelle
item.fluid_storage.1.name=%s1k%s ME-Flüssigkeitsspeicherzelle
item.fluid_storage.4.name=%s4k%s ME-Flüssigkeitsspeicherzelle
item.fluid_storage.16.name=%s16k%s ME-Flüssigkeitsspeicherzelle
item.fluid_storage.64.name=%s64k%s ME-Flüssigkeitsspeicherzelle
item.fluid_storage.256.name=%s256k%s ME-Flüssigkeitsspeicherzelle
item.fluid_storage.1024.name=%s1024k%s ME-Flüssigkeitsspeicherzelle
item.fluid_storage.4096.name=%s4096k%s ME-Flüssigkeitsspeicherzelle
item.fluid_storage.16384.name=%s16384k%s ME-Flüssigkeitsspeicherzelle
item.multi_fluid_storage.1.name=%s1k%s ME-Mehrfach-Flüssigkeitsspeicherzelle
item.multi_fluid_storage.4.name=%s4k%s ME-Mehrfach-Flüssigkeitsspeicherzelle
item.multi_fluid_storage.16.name=%s16k%s ME-Mehrfach-Flüssigkeitsspeicherzelle
item.multi_fluid_storage.64.name=%s64k%s ME-Mehrfach-Flüssigkeitsspeicherzelle
item.multi_fluid_storage.256.name=%s256k%s ME-Mehrfach-Flüssigkeitsspeicherzelle
item.multi_fluid_storage.1024.name=%s1024k%s ME-Mehrfach-Flüssigkeitsspeicherzelle
item.multi_fluid_storage.4096.name=%s4096k%s ME-Mehrfach-Flüssigkeitsspeicherzelle
item.multi_fluid_storage.16384.name=%s16384k%s ME-Mehrfach-Flüssigkeitsspeicherzelle
item.fluid_storage.quantum.name=ME-Flüssigkeits-Quantenspeicherzelle
item.fluid_storage.singularity.name=ME-Flüssigkeits-Digitalsingularitätsspeicherzelle
item.fluid_storage.void.name=Void ME-Flüssigkeitsspeicherzelle
item.fluid_storage.Universe.name=Künstliches Universum-ME-Flüssigkeitsspeicherzelle
item.fluid_storage.infinity.water.name=Unendliche ME-Flüssigkeits-Wasserspeicherzelle
item.fluid_part.name=ME-Flüssigkeitsspeicherkomponente
item.fluid_part.0.name=%s1k%s ME-Flüssigkeitsspeicherkomponente
item.fluid_part.1.name=%s4k%s ME-Flüssigkeitsspeicherkomponente
item.fluid_part.2.name=%s16k%s ME-Flüssigkeitsspeicherkomponente
item.fluid_part.3.name=%s64k%s ME-Flüssigkeitsspeicherkomponente
item.fluid_part.4.name=%s256k%s ME-Flüssigkeitsspeicherkomponente
item.fluid_part.5.name=%s1024k%s ME-Flüssigkeitsspeicherkomponente
item.fluid_part.6.name=%s4096k%s ME-Flüssigkeitsspeicherkomponente
item.fluid_part.7.name=%s16384k%s ME-Flüssigkeitsspeicherkomponente
item.fluid_storage_housing.name=ME-Speichergehäuse
item.fluid_storage_housing.0.name=ME-Flüssigkeitsspeichergehäuse
item.fluid_storage_housing.1.name=Verbessertes ME-Flüssigkeitsspeichergehäuse
item.fluid_storage_housing.2.name=ME-Mehrfach-Flüssigkeitsspeichergehäuse
item.fluid_storage_housing.3.name=Verbessertes ME-Mehrfach-Flüssigkeitsspeichergehäuse
tile.fluid_discretizer.name=Flüssigkeitsdiskretisierer
tile.fluid_pattern_encoder.name=Flüssigkeits-Schablonenkodierer
tile.fluid_packet_decoder.name=ME-Flüssigkeitspaketdekodierer
tile.fluid_interface.name=ME-Dualschnittstelle
tile.ingredient_buffer.name=Eduktpuffer
tile.large_ingredient_buffer.name=Großer Eduktpuffer
tile.oc_pattern_editor.name=OC-Schabloneneditor
tile.level_maintainer.name=ME-Pegelhalter
tile.fluid_buffer.name=ME-Flüssigkeitspuffer
tile.walrus.name=Walross
tile.super_stock_replenisher.name=Super-Vorratsauffüller
tile.fluid_auto_filler.name=ME-Flüssigkeits-Füllautomat
tile.certus_quartz_tank.name=Certusquarztank - %s
tile.certus_quartz_tank_empty.name=Certusquarztank
ae2fc.waila.speed=Geschwindigkeit
ae2fc.waila.enable=An
ae2fc.waila.disable=Aus
ae2fc.tooltip.shift_for_more=§r> §3Shift§r halten für mehr Information
ae2fc.tooltip.ctrl_for_more=§r> §3Strg§r halten für mehr Information
ae2fc.tooltip.fluid_packet_decoder.desc=Der Flüssigkeitsdekodierer kann Flüssigkeitspakete dekodieren. Er muss mit einem ME-System und einem Ort um die Flüssigkeit einzuleiten verbunden sein, sonst funktioniert er nicht.
ae2fc.tooltip.discretizer.desc=Wenn der Flüssigkeitsdiskretisierer an dein ME-System angeschlossen ist, stellt er den Flüssigkeitsvorrat in Lagerzellen (und Lagerbussen) in Tropfen dar. Sie sind das "Item-Äquivalent" zu Flüssigkeiten. Es ist nur eine andere Darstellung für Flüssigkeit, er konvertiert nichts.
ae2fc.tooltip.fluid_buffer.desc=Das ist Highspeed-Flüssigkeitsübertragung
ae2fc.tooltip.walrus.desc=GTNH ist wie Arbeiten
ae2fc.tooltip.fluid_auto_filler=Erstellt automatisch eine Flüssigkeitsbefüllschablone im jeweiligen Container.
ae2fc.tooltip.level_maintainer.Who_Am_I=Wer bin ich?
ae2fc.tooltip.level_maintainer.title=§6Anfragestatus§r
ae2fc.tooltip.level_maintainer.desc=Hält automatisch Items und Flüssigkeiten auf Vorrat, indem es neue Fertigungsaufträge aufgibt. Muss mit einem ME-Netzwerk verbunden sein.
ae2fc.tooltip.level_maintainer.current=Aktuell:
ae2fc.tooltip.level_maintainer.none=Keine Anfrage konfiguriert.
ae2fc.tooltip.level_maintainer.idle=§aNichts zu tun§r
ae2fc.tooltip.level_maintainer.idle_desc=Der Requester ist im Leerlauf wenn der angefragt Vorrat erreicht oder keine Rechenleistung verfügbar ist.
ae2fc.tooltip.level_maintainer.link=§eFertigung§r
ae2fc.tooltip.level_maintainer.link_desc=Das System erstellt die notwendigen Items oder Flüssigkeiten.
ae2fc.tooltip.level_maintainer.export=§5Export§r
ae2fc.tooltip.level_maintainer.export_desc=Der Requester versucht, die Produkte in das System zu exportieren. Wenn der Requester diesen Status für eine längere Zeit hat, ist kein Platz für den Export.
ae2fc.tooltip.level_maintainer.error=§4Fehler§r
ae2fc.tooltip.level_maintainer.error_desc=Der Requester will einen Fertigungsauftrag erstellen aber hat einen internen Fehler.
ae2fc.tooltip.level_maintainer.not_found=§4Nicht Gefunden§r
ae2fc.tooltip.level_maintainer.not_found_desc=Der Requester versucht einen Fertigungsauftrag zu erstellen, findet aber keine Fertigungsschablone.
ae2fc.tooltip.level_maintainer.cant_craft=§4Fertigung nicht möglich§r
ae2fc.tooltip.level_maintainer.cant_craft_desc=Der Requester versucht einen Fertigungsauftrag aufzugeben, aber der Fertigungsmanager kann den Auftrag nicht verarbeiten. (Nicht genug Baumaterialien, Nicht genug Arbeitsspeicher, Rekursion).
ae2fc.tooltip.level_maintainer.batch_size=§6Größe des Fertigungsauftrags§r
ae2fc.tooltip.level_maintainer.batch_size.hint=Wenn Fertigungsaufträge aufgegeben werden, wird der Requester diese Stückzahl anfragen. Größere Stückzahl führt zu schnellerem Wiederauffüllen, braucht aber mehr Fertigungsspeicher.
ae2fc.tooltip.level_maintainer.request_size=§6Soll-Lagerstand§r
ae2fc.tooltip.level_maintainer.request_size.hint=Wieviele Items auf Lager gehalten werden sollen bis der Requester mehr anfragt.
ae2fc.tooltip.ultra_terminal.WIRELESS_CRAFTING_TERMINAL=Modus: Fertigungskonsole
ae2fc.tooltip.ultra_terminal.WIRELESS_FLUID_PATTERN_TERMINAL=Modus: Schablonenkonsole
ae2fc.tooltip.ultra_terminal.WIRELESS_FLUID_TERMINAL=Modus: Flüssigkeitskonsole
ae2fc.tooltip.ultra_terminal.WIRELESS_LEVEL_TERMINAL=Modus: Füllstandkonsole
ae2fc.tooltip.ultra_terminal.WIRELESS_ESSENTIA_TERMINAL=Modus: Essentiakonsole
ae2fc.tooltip.ultra_terminal.WIRELESS_INTERFACE_TERMINAL=Modus: Schnittstellenkonsole
ae2fc.tooltip.ultra_terminal.WIRELESS_FLUID_PATTERN_TERMINAL_EX=Modus: Fertigungsschablonenkonsole
ae2fc.tooltip.ultra_terminal=Rechtsklick + Schleichen, um Modus zu wechseln.
ae2fc.tooltip.ultra_terminal.tips=Tool-Tipps:
ae2fc.tooltip.ultra_terminal.tips.desc=1.Du kannst es in einen Schmuckslot packen, und einen Hotkey zum Öffnen benutzen.\n2.Schnittstellenmodus: Halte §3Shift§7 Schnittstellen-Umbenenn-Knopf.\n3.In der Fertigungsplan-Ansicht\nhalte §3Shift§7 und klicke den "Abbrechen"-Knopf, und die Fehlenden Items\nwerden als NEI-Lesezeichen eingefügt.
ae2fc.tooltip.ultra_terminal.restock.on=Wiederauffüllen an
ae2fc.tooltip.ultra_terminal.restock.off=Wiederauffüllen aus
ae2fc.tooltip.infinity_fluid=§aUnendlich§r
ae2fc.tooltip.fluid_storage.void=Wo nichts alles ist, und alles nichts
ae2fc.tooltip.quantum_bridge_card.desc=Erlaubt es Handkonsolen, sich für unendliche Reichweite mit einer Quantenbrücke zu verbinden
ae2fc.tooltip.energy_card.desc=Unendlich Energie für die Handkonsole
ae2fc.tooltip.cell_contents=Enthält Flüssigkeit:
ae2fc.tooltip.cell_empty=Zelle leer
ae2fc.tooltip.cell_portable=Rechtsklick um Ansicht zu öffnen. Funktioniert wie ein Rucksack, aber du musst sie erst aufladen.
ae2fc.tooltip.fluid_terminal=Also brauchen wir kein EC2 mehr?
ae2fc.tooltip.level_terminal=Äääh...
ae2fc.tooltip.invalid_fluid=Unzulüssige Flüssigkeit!
ae2fc.tooltip.encode_pattern=Schablone kodieren
ae2fc.tooltip.fluid_packet=Benutz einen Flüssigkeitspaketdekodierer\n um hieraus wieder Flüssigkeit zu machen.
ae2fc.tooltip.empty=Leer
ae2fc.tooltip.dump_tank=Tank ausleeren
ae2fc.tooltip.switch_fluid_interface=ME-Dualkonsolenansicht umschalten
ae2fc.tooltip.not_combine=Items vereinigen
ae2fc.tooltip.not_combine.hint=Aus
ae2fc.tooltip.combine=Items vereinigen
ae2fc.tooltip.combine.hint=An
ae2fc.tooltip.fluid_terminal_w=Flüssigkeitskonsole
ae2fc.tooltip.craft_terminal_w=Fertigungskonsole
ae2fc.tooltip.pattern_terminal_w=Schablonenkonsole
ae2fc.tooltip.essentia_terminal_w=Essentiakonsole
ae2fc.tooltip.interface_terminal_w=Schnittstellenkonsole
ae2fc.tooltip.level_terminal_w=Füllstand-Konsole
ae2fc.tooltip.pattern_terminal_ex_w=Verarbeitungsschablonenkonsole
ae2fc.tooltip.wireless.installed=Installierte Karte:
ae2fc.tooltip.not_prio=Flüssigkeiten dürfen zuerst platziert werden
ae2fc.tooltip.not_prio.hint=Aus
ae2fc.tooltip.prio=Flüssigkeiten dürfen zuerst platziert werden
ae2fc.tooltip.prio.hint=An
ae2fc.tooltip.submit=Speichern
ae2fc.tooltip.enable=An
ae2fc.tooltip.disable=Aus
ae2fc.tooltip.edit=Editieren
ae2fc.tooltip.view=Ansehen
ae2fc.tooltip.fill_pattern=Automatisches Füllen von leerer Schablone
ae2fc.tooltip.not_fill_pattern=Automatisches Füllen von leerer Schablone
ae2fc.tooltip.fill_pattern.hint=An
ae2fc.tooltip.not_fill_pattern.hint=Aus
ae2fc.tooltip.open_configuration=Konfiguration öffnen
ae2fc.tooltip.block_highlight=Block hervorheben
ae2fc.tooltip.magnet_card.off=Magnetkarte
ae2fc.tooltip.magnet_card.off.hint=Aus
ae2fc.tooltip.magnet_card.inv=Magnetkarte
ae2fc.tooltip.magnet_card.inv.hint=Ins Inventar aufnehmen
ae2fc.tooltip.magnet_card.me=Magnetkarte
ae2fc.tooltip.magnet_card.me.hint=Ins ME aufnehmen
ae2fc.tooltip.magnet_card.filter=Magnetfilter
ae2fc.tooltip.magnet_card.oreDictFilter=Oredictionary-Filter
ae2fc.tooltip.restock.on=Wiederauffüllen
ae2fc.tooltip.restock.on.hint=An
ae2fc.tooltip.restock.off=Wiederauffüllen
ae2fc.tooltip.restock.off.hint=Aus
ae2fc.gui.part_fluid_pattern_terminal=Flüssigkeitsschablonenkonsole
ae2fc.gui.part_fluid_pattern_terminal_ex=Flüssigkeitsverarbeitungsschablonenkonsole
ae2fc.gui.part_level_terminal=Füllstand-Konsole
ae2fc.gui.fluid_pattern_encoder=Flüssigkeitsschablonenkodierer
ae2fc.gui.fluid_packet_decoder=ME-Flüssigkeitspaketdekodierer
ae2fc.gui.ingredient_buffer=Eduktpuffer
ae2fc.gui.large_ingredient_buffer=Großer Eduktpuffer
ae2fc.gui.fluid_interface=ME-Dualschnittstelle
ae2fc.gui.level_maintainer=ME-Pegelhalter
ae2fc.gui.fluid_interface.0=U
ae2fc.gui.fluid_interface.1=H
ae2fc.gui.fluid_interface.2=N
ae2fc.gui.fluid_interface.3=S
ae2fc.gui.fluid_interface.4=W
ae2fc.gui.fluid_interface.5=O
ae2fc.gui.oc_pattern_editor=OC-Schabloneneditor
ae2fc.gui.button.set=Setzen
ae2fc.gui.part_fluid_level_emitter=ME-Flüssigkeitsfüllstandsemitter
ae2fc.gui.part_fluid_import=ME-Flüssigkeits-Importbus
ae2fc.gui.part_fluid_export=ME-Flüssigkeits-Exportbus
ae2fc.gui.part_fluid_terminal=ME-Flüssigkeitskonsole
ae2fc.gui.part_fluid_storage_bus=ME-Flüssigkeitsspeicherbus
ae2fc.gui.fluid_auto_filler=ME-Flüssigkeits-Füllautomat
ae2fc.gui.magnet=Magnetfilter
ae2fc.gui.magnet.nbt=NBT-Daten ignorieren
ae2fc.gui.magnet.meta=Metadaten ignorieren
ae2fc.gui.magnet.ore=Ore Dictionary benutzen
ae2fc.gui.magnet.whitelist=Whitelist
ae2fc.gui.magnet.blacklist=Blacklist
ae2fc.gui.color.StateNone=00000000
ae2fc.gui.color.StateIdle=FF55FF55
ae2fc.gui.color.StateCraft=FFFFFF55
ae2fc.gui.color.StateExport=FFAA00AA
ae2fc.gui.color.StateError=FFFF5555
error.unknown=Unbekannt
ae2fc.key.OpenTerminal=Handkonsole öffnen
ae2fc.key.Restock=Wiederauffüllen
itemGroup.ae2fc=Flüssigkeitsfertigung für AE2
item.ec2placeholder.oc.upgrade.name=[EC2 PLACEHOLDER] ME-Upgrade
item.ec2placeholder.part.base.name=[EC2 PLACEHOLDER] ME-Flüssigkeitsbus
item.ec2placeholder.pattern.fluid.name=[EC2 PLACEHOLDER] ME-Flüssigkeitsschablone
item.ec2placeholder.storage.casing.name=[EC2 PLACEHOLDER] Speichergehäuse
item.ec2placeholder.storage.component.name=[EC2 PLACEHOLDER] ME-Speicherkomponente
item.ec2placeholder.storage.fluid.name=[EC2 PLACEHOLDER] ME-Flüssigkeitsspeicher
item.ec2placeholder.storage.physical.advanced.quantum.name=[EC2 PLACEHOLDER] ME-Quantenspeicher
item.ec2placeholder.storage.physical.advanced.singularity.name=[EC2 PLACEHOLDER] ME-Digitale Singularität
item.ec2placeholder.storage.physical.name=[EC2 PLACEHOLDER] ME-Speicher
item.ec2placeholder.storage.physical.void.name=[EC2 PLACEHOLDER] Void-ME-Speicher
item.ec2placeholder.terminal.fluid.wireless.name=[EC2 PLACEHOLDER] Flüssigkeits-Handkonsole
item.ec2placeholder.terminal.universal.wireless.name=[EC2 PLACEHOLDER] Universelle Handkonsole
@@ -75,6 +75,7 @@ tile.oc_pattern_editor.name=OC Pattern Editor
tile.level_maintainer.name=ME Level Maintainer
tile.fluid_buffer.name=ME Fluid Buffer
tile.walrus.name=Walrus
tile.super_stock_replenisher.name=Super Stock Replenisher
tile.fluid_auto_filler.name=ME Fluid Auto Filler
tile.certus_quartz_tank.name=Certus Quartz Tank - %s
tile.certus_quartz_tank_empty.name=Certus Quartz Tank
@@ -96,13 +97,17 @@ ae2fc.tooltip.level_maintainer.desc=Automatically keeps items and fluids in stoc
ae2fc.tooltip.level_maintainer.current=Currently:
ae2fc.tooltip.level_maintainer.none=No request configured.
ae2fc.tooltip.level_maintainer.idle=§aIdling§r
ae2fc.tooltip.level_maintainer.idle_desc=The Requester is idling when the requested amount is already reached, there is no crafting pattern for this item or fluid or if there are not enough ingredients to request more crafts.
ae2fc.tooltip.level_maintainer.idle_desc=The Requester is idling when the requested amount is already reached or if no available CPU.
ae2fc.tooltip.level_maintainer.link=§eCrafting§r
ae2fc.tooltip.level_maintainer.link_desc=The system is currently crafting the requested item or fluid.
ae2fc.tooltip.level_maintainer.export=§5Exporting§r
ae2fc.tooltip.level_maintainer.export_desc=The Requester is trying to export the crafting results to the system. If the Requester has this status for a long time, there is no available space for the export.
ae2fc.tooltip.level_maintainer.error=§4Errored§r
ae2fc.tooltip.level_maintainer.error_desc=The Requester is trying to schedule a crafting job but is failing. Possible reasons include a missing recipe or insufficient resources.
ae2fc.tooltip.level_maintainer.error_desc=The Requester is trying to schedule a crafting job but is failing due to internal error.
ae2fc.tooltip.level_maintainer.not_found=§4Not Found§r
ae2fc.tooltip.level_maintainer.not_found_desc=The Requester is trying to schedule a crafting job but can't find a crafting pattern.
ae2fc.tooltip.level_maintainer.cant_craft=§4Can't Craft§r
ae2fc.tooltip.level_maintainer.cant_craft_desc=The Requester is trying to schedule a crafting job but the crafting manager cannot process the job. (not enough ingredients, CPU doesn't have enough memory, recursion).
ae2fc.tooltip.level_maintainer.batch_size=§6Crafting Batch Size§r
ae2fc.tooltip.level_maintainer.batch_size.hint=When craft requests are emitted, the Requester will use the batch size for the request. Using larger batches will increase the speed of stocking up items but will require more crafting storage.
ae2fc.tooltip.level_maintainer.request_size=§6Amount to Maintain§r
+90 -25
View File
@@ -1,23 +1,27 @@
item.fluid_drop.name=Капля (%s)
item.fluid_encoded_pattern.name=Кодированный шаблон
item.fluid_encoded_pattern.name=Закодированный шаблон
item.part_fluid_terminal.name=МЭ жидкостный терминал
item.part_fluid_pattern_terminal.name=МЭ жидкостный терминал шаблонов
item.part_fluid_pattern_terminal_ex.name=МЭ жидкостный терминал шаблонов обработки
item.part_fluid_interface.name=МЭ двойной интерфейс
item.part_fluid_p2p_interface.name=Туннель точка-точка - МЭ двойной интерфейс
item.part_fluid_p2p_interface.name=P2P туннель - МЭ двойной интерфейс
item.part_fluid_import.name=МЭ жидкостная шина импорта
item.part_fluid_export.name=МЭ жидкостная шина экспорта
item.part_fluid_storage_bus.name=МЭ жидкостная шина хранения
item.part_fluid_level_emitter.name=МЭ жидкостный излучатель уровня
item.part_fluid_storage_monitor.name=МЭ жидкостный монитор хранения
item.part_fluid_conversion_monitor.name=МЭ жидкостный монитор преобразования
item.part_level_terminal.name=МЭ Терминал уровня
item.portable_fluid_cell.name=Переносная жидкостная ячейка
item.wireless_fluid_terminal.name=Беспроводной жидкостный терминал
item.wireless_level_terminal.name=Беспроводной терминал уровня
item.wireless_fluid_pattern_terminal.name=Беспроводной жидкостный терминал шаблонов
item.wireless_interface_terminal.name=Беспроводной терминал интерфейсов
item.wireless_ultra_terminal.name=Беспроводной универсальный терминал
item.wireless_ultra_terminal.WIRELESS_CRAFTING_TERMINAL.name=Беспроводной универсальный терминал - Создание
item.wireless_ultra_terminal.WIRELESS_FLUID_PATTERN_TERMINAL.name=Беспроводной универсальный терминал - Шаблон
item.wireless_ultra_terminal.WIRELESS_FLUID_TERMINAL.name=Беспроводной универсальный терминал - Жидкость
item.wireless_ultra_terminal.WIRELESS_LEVEL_TERMINAL.name=Беспроводной универсальный терминал - Уровень
item.wireless_ultra_terminal.WIRELESS_ESSENTIA_TERMINAL.name=Беспроводной универсальный терминал - Эссенция
item.wireless_ultra_terminal.WIRELESS_INTERFACE_TERMINAL.name=Беспроводной универсальный терминал - Интерфейс
item.wireless_ultra_terminal.WIRELESS_FLUID_PATTERN_TERMINAL_EX.name=Беспроводной универсальный терминал - Шаблон обработки
@@ -42,8 +46,11 @@ item.multi_fluid_storage.1024.name=%s1024К%s МЭ мульти-жидкостн
item.multi_fluid_storage.4096.name=%s4096К%s МЭ мульти-жидкостная ячейка хранения
item.multi_fluid_storage.16384.name=%s16384К%s МЭ мульти-жидкостная ячейка хранения
item.fluid_storage.quantum.name=МЭ жидкостная квантовая ячейка хранения
item.fluid_storage.singularity.name=МЭ жидкостная цифровая сингулярность
item.fluid_storage.infinity.water.name=ME жидкостная ячейка хранения бесконечной воды
item.fluid_storage.singularity.name=МЭ жидкостная сингулярная ячейка хранения
item.fluid_storage.void.name=МЭ пустотная жидкостная ячейка
item.fluid_storage.Universe.name=МЭ жидкостная ячейка хранения искусственной вселенной
item.fluid_storage.infinity.water.name=МЭ жидкостная ячейка хранения бесконечной воды
item.fluid_part.name=МЭ жидкостный компонент хранения
item.fluid_part.0.name=%s1К%s МЭ жидкостный компонент хранения
item.fluid_part.1.name=%s4К%s МЭ жидкостный компонент хранения
item.fluid_part.2.name=%s16К%s МЭ жидкостный компонент хранения
@@ -52,10 +59,11 @@ item.fluid_part.4.name=%s256К%s МЭ жидкостный компонент х
item.fluid_part.5.name=%s1024К%s МЭ жидкостный компонент хранения
item.fluid_part.6.name=%s4096К%s МЭ жидкостный компонент хранения
item.fluid_part.7.name=%s16384К%s МЭ жидкостный компонент хранения
item.fluid_storage_housing.0.name=МЭ жидкостный корпус ячейки хранения
item.fluid_storage_housing.1.name=МЭ продвинутый жидкостный корпус ячейки хранения
item.fluid_storage_housing.2.name=МЭ мульти-жидкостный корпус ячейки хранения
item.fluid_storage_housing.3.name=МЭ продвинутый мульти-жидкостный корпус ячейки хранения
item.fluid_storage_housing.name=МЭ корпус ячейки хранения
item.fluid_storage_housing.0.name=МЭ корпус жидкостной ячейки хранения
item.fluid_storage_housing.1.name=МЭ улучшенный корпус жидкостной ячейки хранения
item.fluid_storage_housing.2.name=МЭ корпус мульти-жидкостной ячейки хранения
item.fluid_storage_housing.3.name=МЭ улучшенный корпус мульти-жидкостной ячейки хранения
tile.fluid_discretizer.name=Дискретизатор жидкости
tile.fluid_pattern_encoder.name=Кодировщик жидкостных шаблонов
@@ -67,13 +75,14 @@ tile.oc_pattern_editor.name=OC редактор шаблонов
tile.level_maintainer.name=МЭ поддерживатель уровня
tile.fluid_buffer.name=МЭ жидкостный буфер
tile.walrus.name=Морж
tile.super_stock_replenisher.name=Супер-пополнитель запасов
tile.fluid_auto_filler.name=МЭ жидкостный авто-заполнитель
tile.certus_quartz_tank.name=Резервуар из истинного кварца - %s
tile.certus_quartz_tank_empty.name=Резервуар из истинного кварца
ae2fc.waila.speed=Скорость
ae2fc.waila.enable=Включено
ae2fc.waila.disable=Выключено
ae2fc.waila.disable=Отключено
ae2fc.tooltip.shift_for_more=§r> Удерживайте §3Shift§r для подробностей
ae2fc.tooltip.ctrl_for_more=§r> Удерживайте §3Ctrl§r для подробностей
@@ -85,28 +94,38 @@ ae2fc.tooltip.fluid_auto_filler=Автоматически создаёт шаб
ae2fc.tooltip.level_maintainer.Who_Am_I=Кто я?
ae2fc.tooltip.level_maintainer.title=§6Статус запроса§r
ae2fc.tooltip.level_maintainer.desc=Автоматически поддерживает заданное количество предметов и жидкостей в хранилище, запрашивая новые при необходимости. Должен быть подключен к МЭ сети.
ae2fc.tooltip.level_maintainer.current=Текущее состояние:
ae2fc.tooltip.level_maintainer.current=Текущее состояние:
ae2fc.tooltip.level_maintainer.none=Запрос не настроен.
ae2fc.tooltip.level_maintainer.idle=§aБездействие§r
ae2fc.tooltip.level_maintainer.idle_desc=Запрашиватель бездействует, когда запрошенное количество уже достигнуто, нет шаблона создания этого предмета или жидкости или если недостаточно ингредиентов, чтобы запросить больше.
ae2fc.tooltip.level_maintainer.idle_desc=Поддерживатель бездействует, когда запрошенное количество уже достигнуто или если нет доступного ЦП.
ae2fc.tooltip.level_maintainer.link=§eСоздание§r
ae2fc.tooltip.level_maintainer.link_desc=В данный момент система создаёт запрашиваемый предмет или жидкость.
ae2fc.tooltip.level_maintainer.export=§5Экспорт§r
ae2fc.tooltip.level_maintainer.export_desc=Запрашиватель пытается поместить результаты создания в систему. Если запрашиватель находится в этом состоянии длительное время, значит в системе недостаточно свободного места для экспорта.
ae2fc.tooltip.level_maintainer.export_desc=Поддерживатель пытается поместить результаты создания в систему. Если Поддерживатель находится в этом состоянии длительное время, значит в системе недостаточно свободного места для экспорта.
ae2fc.tooltip.level_maintainer.error=§4Ошибка§r
ae2fc.tooltip.level_maintainer.error_desc=Поддерживатель пытается запланировать работу по созданию, но ему это не удается из-за внутренней ошибки.
ae2fc.tooltip.level_maintainer.not_found=§4Не найдено§r
ae2fc.tooltip.level_maintainer.not_found_desc=Поддерживатель пытается запланировать задание на создание, но не может найти шаблон создание.
ae2fc.tooltip.level_maintainer.cant_craft=§4Невозможно создать§r
ae2fc.tooltip.level_maintainer.cant_craft_desc=Поддерживатель пытается запланировать задание на создание, но менеджер создание не может его обработать (не хватает ингредиентов, у процессора недостаточно памяти, рекурсия).
ae2fc.tooltip.level_maintainer.batch_size=§6Размер партии создания§r
ae2fc.tooltip.level_maintainer.batch_size.hint=Запрашиватель будет использовать указанный размер партии при появлении запроса на создание. Использование больших значений увеличит скорость пополнения предметов, но потребует увеличение количества хранилищ создания.
ae2fc.tooltip.level_maintainer.batch_size.hint=Поддерживатель будет использовать указанный размер партии при появлении запроса на создание. Использование больших значений увеличит скорость пополнения предметов, но потребует увеличение количества хранилищ создания.
ae2fc.tooltip.level_maintainer.request_size=§6Количество для поддержания§r
ae2fc.tooltip.level_maintainer.request_size.hint=Счетчик определяет, сколько предметов должно находится в хранилище, прежде чем запрашиватель отправит запрос на создание.
ae2fc.tooltip.level_maintainer.request_size.hint=Счетчик определяет, сколько предметов должно находится в хранилище, прежде чем Поддерживатель отправит запрос на создание.
ae2fc.tooltip.ultra_terminal.WIRELESS_CRAFTING_TERMINAL=Режим: Терминал создания
ae2fc.tooltip.ultra_terminal.WIRELESS_FLUID_PATTERN_TERMINAL=Режим: Терминал шаблонов
ae2fc.tooltip.ultra_terminal.WIRELESS_FLUID_TERMINAL=Режим: Жидкостный терминал
ae2fc.tooltip.ultra_terminal.WIRELESS_LEVEL_TERMINAL=Режим: Терминал уровня
ae2fc.tooltip.ultra_terminal.WIRELESS_ESSENTIA_TERMINAL=Режим: Терминал эссенции
ae2fc.tooltip.ultra_terminal.WIRELESS_INTERFACE_TERMINAL=Режим: Терминал интерфейсов
ae2fc.tooltip.ultra_terminal.WIRELESS_FLUID_PATTERN_TERMINAL_EX=Режим: Терминал шаблонов обработки
ae2fc.tooltip.ultra_terminal=ПКМ+Shift, чтобы изменить режим.
ae2fc.tooltip.ultra_terminal=Shift+ПКМ, чтобы изменить режим.
ae2fc.tooltip.ultra_terminal.tips=Подсказки:
ae2fc.tooltip.ultra_terminal.tips.desc=1. Вы можете поместить его в слот Baubles и открыть с помощью привязанной клавиши.\n2. Режим интерфейсов. Удерживайте §3Shift§7 для переключения между кнопками подсветки и переименовывания интерфейсов.\n3. Экран "План создания".\nУдерживая §3Shift§7 нажмите кнопку "Отмена", чтобы автоматически добавить все недостающие ингредиенты в панель закладок NEI.
ae2fc.tooltip.ultra_terminal.restock.on=Автопополнение запасов активировать
ae2fc.tooltip.ultra_terminal.restock.off=Автопополнение запасов деактивировать
ae2fc.tooltip.infinity_fluid=§aБесконечная/ый§r
ae2fc.tooltip.fluid_storage.void=Где ничто есть всё, а всё есть ничто
ae2fc.tooltip.quantum_bridge_card.desc=Позволяет беспроводным терминалам подключаться к квантовому мосту, обеспечивая неограниченный радиус действия
ae2fc.tooltip.energy_card.desc=Бесконечная энергия для беспроводного терминала
@@ -115,6 +134,7 @@ ae2fc.tooltip.cell_contents=Содержит жидкость:
ae2fc.tooltip.cell_empty=Ячейка пуста
ae2fc.tooltip.cell_portable=Нажмите ПКМ для открытия её интерфейса. Работает как рюкзак, но её необходимо зарядить перед использованием.
ae2fc.tooltip.fluid_terminal=Эмм, нам больше не нужен EC2?
ae2fc.tooltip.level_terminal=Эмм...
ae2fc.tooltip.invalid_fluid=Неверная жидкость!
ae2fc.tooltip.encode_pattern=Закодировать шаблон
ae2fc.tooltip.fluid_packet=Используйте декодер жидкостных пакетов,\nчтобы преобразовать это обратно в жидкость.
@@ -122,7 +142,7 @@ ae2fc.tooltip.empty=Пусто
ae2fc.tooltip.dump_tank=Слить содержимое резервуара
ae2fc.tooltip.switch_fluid_interface=Переключить GUI МЭ двойного интерфейса
ae2fc.tooltip.not_combine=Объединять одинаковые предметы
ae2fc.tooltip.not_combine.hint=Выключено
ae2fc.tooltip.not_combine.hint=Отключено
ae2fc.tooltip.combine=Объединять одинаковые предметы
ae2fc.tooltip.combine.hint=Включено
ae2fc.tooltip.fluid_terminal_w=Жидкостный терминал
@@ -130,24 +150,42 @@ ae2fc.tooltip.craft_terminal_w=Терминал создания
ae2fc.tooltip.pattern_terminal_w=Терминал шаблонов
ae2fc.tooltip.essentia_terminal_w=Терминал эссенции
ae2fc.tooltip.interface_terminal_w=Терминал интерфейсов
ae2fc.tooltip.level_terminal_w=Терминал уровня
ae2fc.tooltip.pattern_terminal_ex_w=Терминал шаблонов обработки
ae2fc.tooltip.wireless.installed=Установленные карты:
ae2fc.tooltip.not_prio=Помещать жидкость первой
ae2fc.tooltip.not_prio.hint=Включено
ae2fc.tooltip.not_prio.hint=Отключено
ae2fc.tooltip.prio=Помещать жидкость первой
ae2fc.tooltip.prio.hint=Выключено
ae2fc.tooltip.prio.hint=Включено
ae2fc.tooltip.submit=Подтвердить
ae2fc.tooltip.enable=Включено
ae2fc.tooltip.disable=Выключено
ae2fc.tooltip.edit=Редактировать
ae2fc.tooltip.fill_pattern=Разрешить авто-заполнение пустых шаблонов
ae2fc.tooltip.not_fill_pattern=Разрешить авто-заполнение пустых шаблонов
ae2fc.tooltip.disable=Отключено
ae2fc.tooltip.edit=Изменить
ae2fc.tooltip.view=Вид
ae2fc.tooltip.fill_pattern=Разрешить автопополнение пустыми шаблонами
ae2fc.tooltip.not_fill_pattern=Разрешить автопополнение пустыми шаблонами
ae2fc.tooltip.fill_pattern.hint=Включено
ae2fc.tooltip.not_fill_pattern.hint=Выключено
ae2fc.tooltip.not_fill_pattern.hint=Отключено
ae2fc.tooltip.open_configuration=Открыть настройки
ae2fc.tooltip.block_highlight=Подсветить блок
ae2fc.tooltip.magnet_card.off=Магнитная карта
ae2fc.tooltip.magnet_card.off.hint=Откл.
ae2fc.tooltip.magnet_card.inv=Магнитная карта
ae2fc.tooltip.magnet_card.inv.hint=Подбирать в инвентарь
ae2fc.tooltip.magnet_card.me=Магнитная карта
ae2fc.tooltip.magnet_card.me.hint=Подбирать в МЭ
ae2fc.tooltip.magnet_card.filter=Фильтр магнита
ae2fc.tooltip.magnet_card.oreDictFilter=Фильтрация по словарю руд
ae2fc.tooltip.restock.on=Автопополнение запасов
ae2fc.tooltip.restock.on.hint=Включить
ae2fc.tooltip.restock.off=Автопополнение запасов
ae2fc.tooltip.restock.off.hint=Отключить
ae2fc.gui.part_fluid_pattern_terminal=Жидкостный терминал шаблонов
ae2fc.gui.part_fluid_pattern_terminal_ex=Жидкостный терминал шаблонов обработки
ae2fc.gui.part_level_terminal=Терминал уровня
ae2fc.gui.fluid_pattern_encoder=Кодировщик жидкостных шаблонов
ae2fc.gui.fluid_packet_decoder=МЭ декодер жидкостных пакетов
ae2fc.gui.ingredient_buffer=Буфер ингредиентов
@@ -162,15 +200,42 @@ ae2fc.gui.fluid_interface.4=Зап
ae2fc.gui.fluid_interface.5=Вос
ae2fc.gui.oc_pattern_editor=OC редактор шаблонов
ae2fc.gui.button.set=Задать
ae2fc.gui.part_fluid_level_emitter=МЭ излучатель уровня
ae2fc.gui.part_fluid_level_emitter=МЭ жидкостный излучатель уровня
ae2fc.gui.part_fluid_import=МЭ жидкостная шина импорта
ae2fc.gui.part_fluid_export=МЭ жидкостная шина экспорта
ae2fc.gui.part_fluid_terminal=МЭ жидкостный терминал
ae2fc.gui.part_fluid_storage_bus=МЭ жидкостная шина хранения
ae2fc.gui.fluid_auto_filler=МЭ жидкостный авто-заполнитель
ae2fc.gui.magnet=Фильтр магнита
ae2fc.gui.magnet.nbt=Игнорировать NBT
ae2fc.gui.magnet.meta=Игнорировать метаданные
ae2fc.gui.magnet.ore=Использовать словарь руд
ae2fc.gui.magnet.whitelist=Белый список
ae2fc.gui.magnet.blacklist=Чёрный список
ae2fc.gui.color.StateNone=00000000
ae2fc.gui.color.StateIdle=FF55FF55
ae2fc.gui.color.StateCraft=FFFFFF55
ae2fc.gui.color.StateExport=FFAA00AA
ae2fc.gui.color.StateError=FFFF5555
error.unknown=Неизвестно
key.OpenTerminal=Открыть беспроводной универсальный терминал
ae2fc.key.OpenTerminal=Открыть беспроводной универсальный терминал
ae2fc.key.Restock=Автопополнение запасов
itemGroup.ae2fc=Fluid Craft For AE2
item.ec2placeholder.oc.upgrade.name=[EC2 ЗАПОЛНИТЕЛЬ] МЭ улучшение
item.ec2placeholder.part.base.name=[EC2 ЗАПОЛНИТЕЛЬ] МЭ жидкостная шина
item.ec2placeholder.pattern.fluid.name=[EC2 ЗАПОЛНИТЕЛЬ] МЭ жидкостной шаблон
item.ec2placeholder.storage.casing.name=[EC2 ЗАПОЛНИТЕЛЬ] Ячейка хранения
item.ec2placeholder.storage.component.name=[EC2 ЗАПОЛНИТЕЛЬ] МЭ компонент хранения
item.ec2placeholder.storage.fluid.name=[EC2 ЗАПОЛНИТЕЛЬ] МЭ жидкостная ячейка хранения
item.ec2placeholder.storage.physical.advanced.quantum.name=[EC2 ЗАПОЛНИТЕЛЬ] МЭ квантовая ячейка хранения
item.ec2placeholder.storage.physical.advanced.singularity.name=[EC2 ЗАПОЛНИТЕЛЬ] МЭ сингулярная ячейка хранения
item.ec2placeholder.storage.physical.name=[EC2 ЗАПОЛНИТЕЛЬ] МЭ ячейка хранения
item.ec2placeholder.storage.physical.void.name=[EC2 ЗАПОЛНИТЕЛЬ] МЭ пустотная ячейка хранения
item.ec2placeholder.terminal.fluid.wireless.name=[EC2 ЗАПОЛНИТЕЛЬ] Беспроводной жидкостный терминал
item.ec2placeholder.terminal.universal.wireless.name=[EC2 ЗАПОЛНИТЕЛЬ] Беспроводной универсальный терминал
Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB