Compare commits

...

27 Commits

Author SHA1 Message Date
NotMyWing 26bb5986c6 Temporary OreDict bus serialization fix
Fixes #542
2025-03-25 16:57:55 +11:00
NotMyWing e175bccace Fix Color Applicator model
Closes #518
2025-03-18 20:02:51 +11:00
NotMyWing 127872b310 Fix Wireless Interface Terminal hotkey
Closes #537
2025-03-18 18:37:00 +11:00
NotMyWing b030cb9f00 Fix slot OOB indexing 2025-03-18 18:30:44 +11:00
NotMyWing f1e5a33a6e Fix ME Portable Cell voiding/dupes & disabled slot idiocy
Fixes #383, fixes #299
2025-03-18 18:22:03 +11:00
NotMyWing f42a5778d2 Display lock reason only when using the mode 2025-03-14 15:48:23 +11:00
Neeve d131e12498 Generalize ME Interface blocking logic (#531) 2025-03-14 15:33:58 +11:00
Neeve f1d9fda6ce Split injecting into CraftingGridCache into separate pass (#533) 2025-03-14 14:17:29 +11:00
zeng-git 2141ffe7f0 Update build actions (#475) 2025-03-13 17:22:09 +11:00
NotMyWing 7baf538a76 Fix stack sizes underflowing when shift-clicking into oversized slots
Fixes #519
2025-03-11 19:11:08 +11:00
zeng-git e833aa1e61 Further crafting lock improvements (#507) 2025-03-10 18:40:11 +11:00
Ghzdude 202259ef2a Make FluidHandlerAdapter Cache properly use Tank Properties (#483) 2025-03-10 18:36:31 +11:00
Yang Xizhi fabc9bd82c Fix ME Interface deadlocking (#478) 2025-03-10 18:35:31 +11:00
zeng-git 9c021867f0 Add Wireless Interface Terminal (#500) 2025-03-10 18:33:10 +11:00
Forever-178 9749faa692 Fix ME Interface Terminal localization (#522) 2025-03-10 17:06:22 +11:00
zeng-git 37e7c02c3c Fix Annihilation Plane sometimes not accepting drops (#524) 2025-03-10 16:59:04 +11:00
zeng-git 7f2318f89c Add Annihilation Plane enchantment support, deprecate Identity (#510) 2024-11-29 16:06:55 +11:00
zeng-git 925cf092be Backport colored tooltips from modern AE2 (#503) 2024-11-29 14:39:03 +11:00
RuiXuqi 7c6ceefd94 Change lock/unlock icon to fit the old style (#466) 2024-06-21 13:40:21 +11:00
NotMyWing c7ec7e0890 Hide all facades from JEI except for the first found
Closes #457
2024-06-18 20:14:33 +11:00
Yang Xizhi 0a7799a664 Allow looking up recipes in JEI with non-item slots (#451) 2024-06-18 19:14:20 +11:00
jchung01 1316f035cd Fix some MouseTweaks interactions (#455) 2024-06-18 19:12:03 +11:00
brachy84 10a0453bea Fix nullable Inscriber inputs (#464) 2024-06-18 19:11:44 +11:00
Yang Xizhi efe726ecdd Fix ME Interfaces not pulling items from storage (#454) 2024-06-13 13:57:37 +11:00
NotMyWing 9a255432f5 Publish to the GTCEu Maven 2024-06-10 18:16:12 +11:00
NotMyWing eba3e2456a Add custom TunnelType registration API 2024-06-10 18:12:02 +11:00
NotMyWing d40b9831c1 Make craftingList a hash set in DualityInterface
Improves pattern lookup times, even though I'm not sure why this check even exist
2024-06-10 15:40:28 +11:00
74 changed files with 1600 additions and 346 deletions
+6 -4
View File
@@ -6,16 +6,18 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up OpenJDK 17
uses: actions/setup-java@v2
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'adopt' # You can choose other OpenJDK distributions.
- name: Update Build Script (Before Build)
run: ./gradlew updateBuildScript
- name: Build with Gradle
run: ./gradlew build # Ensure your gradlew script is executable
run: ./gradlew build
- name: Upload Artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: AE2-UEL
path: build/libs/*.jar # Make sure this path matches the location of your build artifacts
+14
View File
@@ -52,6 +52,20 @@ jobs:
generate_release_notes: true
fail_on_unmatched_files: true
- name: Publish to Maven
uses: gradle/gradle-build-action@v2
env:
MAVEN_USER: "${{secrets.MAVEN_USER}}"
MAVEN_PASSWORD: "${{secrets.MAVEN_PASSWORD}}"
with:
arguments: 'publish --daemon'
generate-job-summary: false
gradle-home-cache-includes: |
caches
jdks
notifications
wrapper
- name: Publish to Curseforge
uses: gradle/gradle-build-action@v2
env:
+1 -1
View File
@@ -153,7 +153,7 @@ noPublishedSources = false
# For maven credentials:
# Username is set with the 'MAVEN_USER' environment variable, default to "NONE"
# Password is set with the 'MAVEN_PASSWORD' environment variable, default to "NONE"
customMavenPublishUrl =
customMavenPublishUrl = https://maven.gtceu.com
# The group for maven artifacts. Defaults to the 'project.modGroup' until the last '.' (if any).
# So 'mymod' becomes 'mymod' and 'com.myname.mymodid' 'becomes com.myname'
@@ -6,21 +6,21 @@ public enum LockCraftingMode {
*/
NONE,
/**
* After pushing a pattern to an adjacent machine, the pattern provider will not accept further crafts until a
* After pushing a pattern to an adjacent machine, the interface will not accept further crafts until a
* redstone pulse is received.
*/
LOCK_UNTIL_PULSE,
/**
* Crafting is locked while the pattern provider is receiving a redstone signal.
* Crafting is locked while the interface is receiving a redstone signal.
*/
LOCK_WHILE_HIGH,
/**
* Crafting is locked while the pattern provider is not receiving a redstone signal.
* Crafting is locked while the interface is not receiving a redstone signal.
*/
LOCK_WHILE_LOW,
/**
* After pushing a pattern to an adjacent machine, the pattern provider will not accept further crafts until the
* primary pattern result is returned to the network through the pattern provider.
* After pushing a pattern to an adjacent machine, the interface will not accept further crafts until the
* primary pattern result is returned to the network through the interface.
*/
LOCK_UNTIL_RESULT
}
+61 -12
View File
@@ -24,16 +24,65 @@
package appeng.api.config;
public enum TunnelType
{
ME, // Network Tunnel
IC2_POWER, // EU Tunnel
FE_POWER, // Forge Energy tunnel
GTEU_POWER, // Forge Energy tunnel
REDSTONE, // Redstone Tunnel
FLUID, // Fluid Tunnel
ITEM, // Item Tunnel
LIGHT, // Light Tunnel
BUNDLED_REDSTONE, // Bundled Redstone Tunnel
COMPUTER_MESSAGE // Computer Message Tunnel
import appeng.api.AEApi;
import appeng.api.definitions.IItemDefinition;
import appeng.api.definitions.IParts;
import appeng.api.parts.IPartItem;
import com.google.common.base.Preconditions;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.EnumHelper;
import javax.annotation.Nonnull;
import java.util.function.Function;
import java.util.function.Supplier;
public enum TunnelType {
ME(tryPartStack(IParts::p2PTunnelME)),
IC2_POWER(tryPartStack(IParts::p2PTunnelEU)),
FE_POWER(tryPartStack(IParts::p2PTunnelFE)),
GTEU_POWER(tryPartStack(IParts::p2PTunnelGTEU)),
REDSTONE(tryPartStack(IParts::p2PTunnelRedstone)),
FLUID(tryPartStack(IParts::p2PTunnelFE)),
ITEM(tryPartStack(IParts::p2PTunnelItems)),
LIGHT(tryPartStack(IParts::p2PTunnelLight));
private ItemStack partItemStack;
private Supplier<ItemStack> partItemStackSupplier;
@Deprecated
TunnelType() {
this.partItemStack = ItemStack.EMPTY;
this.partItemStackSupplier = null;
}
// Public facing.
TunnelType(ItemStack partItemStack) {
this.partItemStack = partItemStack;
this.partItemStackSupplier = null;
}
// Work around things instantiating this class too early.
TunnelType(Supplier<ItemStack> supplier) {
this.partItemStack = null;
this.partItemStackSupplier = supplier;
}
private static Supplier<ItemStack> tryPartStack(Function<IParts, IItemDefinition> supplier) {
return () -> supplier.apply(AEApi.instance().definitions().parts()).maybeStack(1).orElse(ItemStack.EMPTY);
}
public static TunnelType registerTunnelType(@Nonnull String name, @Nonnull ItemStack partItemStack) {
Preconditions.checkArgument(partItemStack.isEmpty() || partItemStack.getItem() instanceof IPartItem<?>,
"Part item must be an instance of IPartItem");
return EnumHelper.addEnum(TunnelType.class, name, new Class[]{ItemStack.class}, partItemStack);
}
public ItemStack getPartItemStack() {
if (this.partItemStackSupplier != null) {
this.partItemStack = this.partItemStackSupplier.get();
this.partItemStackSupplier = null;
}
return partItemStack;
}
}
@@ -67,6 +67,8 @@ public interface IItems {
IItemDefinition wirelessPatternTerminal();
IItemDefinition wirelessInterfaceTerminal();
IItemDefinition wirelessFluidTerminal();
IItemDefinition biometricCard();
@@ -24,13 +24,12 @@
package appeng.api.features;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import appeng.api.config.TunnelType;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.capabilities.Capability;
import appeng.api.config.TunnelType;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
@@ -59,6 +58,8 @@ public interface IP2PTunnelRegistry
*
* @return null if no attunement can be found or attunement
*/
@Nonnull
@Nullable
TunnelType getTunnelTypeByItem( ItemStack trigger );
TunnelType registerTunnelType( @Nonnull String enumName, @Nonnull ItemStack partStack );
}
@@ -21,11 +21,10 @@ package appeng.block;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.PowerUnits;
import appeng.api.definitions.IBlockDefinition;
import appeng.api.implementations.items.IAEItemPowerStorage;
import appeng.core.Api;
import appeng.core.localization.GuiText;
import appeng.core.localization.Tooltips;
import appeng.util.Platform;
import net.minecraft.block.Block;
import net.minecraft.client.util.ITooltipFlag;
@@ -35,7 +34,6 @@ import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.text.MessageFormat;
import java.util.List;
@@ -57,10 +55,7 @@ public class AEBaseItemBlockChargeable extends AEBaseItemBlock implements IAEIte
internalCurrentPower = tag.getDouble("internalCurrentPower");
}
final double percent = internalCurrentPower / internalMaxPower;
lines.add(GuiText.StoredEnergy.getLocal() + ':' + MessageFormat.format(" {0,number,#} ", internalCurrentPower) + Platform
.gui_localize(PowerUnits.AE.unlocalizedName) + " - " + MessageFormat.format(" {0,number,#.##%} ", percent));
lines.add(Tooltips.energyStorageComponent(internalCurrentPower, internalMaxPower).getFormattedText());
}
}
+4 -16
View File
@@ -46,7 +46,6 @@ import appeng.helpers.IMouseWheelItem;
import appeng.hooks.TickHandler;
import appeng.hooks.TickHandler.PlayerColor;
import appeng.items.tools.powered.Terminal;
import appeng.items.tools.powered.ToolWirelessTerminal;
import appeng.server.ServerHelper;
import appeng.util.Platform;
import net.minecraft.client.Minecraft;
@@ -54,7 +53,6 @@ import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Items;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumHand;
@@ -63,8 +61,6 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.client.event.*;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.settings.KeyConflictContext;
import net.minecraftforge.client.settings.KeyModifier;
import net.minecraftforge.common.ForgeModContainer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.FMLClientHandler;
@@ -73,22 +69,12 @@ import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.*;
import static appeng.client.KeyBindings.WCT;
import static appeng.client.KeyBindings.WFT;
import static appeng.client.KeyBindings.WPT;
import static appeng.client.KeyBindings.WT;
import static appeng.client.KeyBindings.*;
public class ClientHelper extends ServerHelper {
@@ -354,6 +340,8 @@ public class ClientHelper extends ServerHelper {
NetworkHandler.instance().sendToServer(new PacketTerminalUse(Terminal.WIRELESS_PATTERN_TERMINAL));
} else if (k == WFT.getKeyBinding()) {
NetworkHandler.instance().sendToServer(new PacketTerminalUse(Terminal.WIRELESS_FLUID_TERMINAL));
} else if (k == WIT.getKeyBinding()) {
NetworkHandler.instance().sendToServer(new PacketTerminalUse(Terminal.WIRELESS_INTERFACE_TERMINAL));
}
}
}
+2 -1
View File
@@ -12,7 +12,8 @@ public enum KeyBindings {
WT(new KeyBinding("key.open_wireless_terminal.desc", KeyConflictContext.UNIVERSAL, KeyModifier.SHIFT, Keyboard.KEY_T, KEY_CATEGORY)),
WCT(new KeyBinding("key.open_wireless_crafting_terminal.desc", KeyConflictContext.UNIVERSAL, KeyModifier.SHIFT, Keyboard.KEY_E, KEY_CATEGORY)),
WPT(new KeyBinding("key.open_wireless_pattern_terminal.desc", KeyConflictContext.UNIVERSAL, KeyModifier.SHIFT, Keyboard.KEY_R, KEY_CATEGORY)),
WFT(new KeyBinding("key.open_wireless_fluid_terminal.desc", KeyConflictContext.UNIVERSAL, KeyModifier.SHIFT, Keyboard.KEY_F, KEY_CATEGORY));
WFT(new KeyBinding("key.open_wireless_fluid_terminal.desc", KeyConflictContext.UNIVERSAL, KeyModifier.SHIFT, Keyboard.KEY_F, KEY_CATEGORY)),
WIT(new KeyBinding("key.open_wireless_interface_terminal.desc",KeyConflictContext.UNIVERSAL,KeyModifier.SHIFT,Keyboard.KEY_I,KEY_CATEGORY));
private KeyBinding keyBinding;
+17 -3
View File
@@ -183,6 +183,12 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
this.drawTooltip((ITooltip) c, mouseX, mouseY);
}
}
for (final Object o : this.labelList) {
if (o instanceof ITooltip) {
this.drawTooltip((ITooltip) o, mouseX, mouseY);
}
}
GlStateManager.enableDepth();
if (Platform.isModLoaded("jei")) {
bookmarkedJEIghostItem(mouseX, mouseY);
@@ -1057,7 +1063,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_isMouseTweaksDisabled() {
return true;
return false;
}
@Override
@@ -1087,12 +1093,20 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_isIgnored(Slot slot) {
return true;
return false;
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_disableRMBDraggingFunctionality() {
return true;
if (this.dragSplitting && this.dragSplittingButton == 1) {
this.dragSplitting = false;
// Don't ignoreMouseUp on slots that can't accept the item. (crafting output, ME slot, etc.)
if (this.getSlotUnderMouse() != null && this.getSlotUnderMouse().isItemValid(this.mc.player.inventory.getItemStack())) {
this.ignoreMouseUp = true;
}
return true;
}
return false;
}
}
@@ -7,11 +7,15 @@ import appeng.client.gui.implementations.GuiCraftingCPU;
import appeng.client.gui.implementations.GuiExpandedProcessingPatternTerm;
import appeng.client.gui.implementations.GuiPatternTerm;
import appeng.client.gui.implementations.GuiUpgradeable;
import appeng.client.gui.widgets.GuiCustomSlot;
import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.container.interfaces.ISpecialSlotIngredient;
import appeng.container.slot.IJEITargetSlot;
import mezz.jei.api.gui.IAdvancedGuiHandler;
import mezz.jei.api.gui.IGhostIngredientHandler;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Slot;
import org.lwjgl.input.Mouse;
import javax.annotation.Nonnull;
@@ -63,11 +67,39 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngre
if (guiContainer instanceof GuiCraftAmount) {
if (guiContainer.getSlotUnderMouse() != null) {
result = guiContainer.getSlotUnderMouse().getStack();
} else {
return null;
}
}
if (result != null) {
return result;
}
Slot slot = guiContainer.getSlotUnderMouse();
if (slot instanceof ISpecialSlotIngredient ss) {
return ss.getIngredient();
}
for (GuiCustomSlot customSlot : guiContainer.guiSlots) {
if (this.checkSlotArea(guiContainer, customSlot, mouseX, mouseY)) {
return customSlot.getIngredient();
}
}
return result;
}
private boolean checkSlotArea(GuiContainer gui, GuiCustomSlot slot, int mouseX, int mouseY) {
int i = gui.guiLeft;
int j = gui.guiTop;
mouseX = mouseX - i;
mouseY = mouseY - j;
return mouseX >= slot.xPos() - 1 &&
mouseX < slot.xPos() + slot.getWidth() + 1 &&
mouseY >= slot.yPos() - 1 &&
mouseY < slot.yPos() + slot.getHeight() + 1;
}
private int getSlotidx(AEBaseGui guiContainer, int mouseX, int mouseY, int rows) {
int guileft = guiContainer.getGuiLeft();
int guitop = guiContainer.getGuiTop();
@@ -23,6 +23,7 @@ import appeng.api.config.LockCraftingMode;
import appeng.api.config.Settings;
import appeng.api.config.YesNo;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiImgLabel;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.client.gui.widgets.GuiToggleButton;
import appeng.container.implementations.ContainerInterface;
@@ -45,12 +46,19 @@ public class GuiInterface extends GuiUpgradeable {
private GuiImgButton UnlockMode;
private GuiImgButton BlockMode;
private GuiToggleButton interfaceMode;
private GuiImgLabel lockReason;
public GuiInterface(final InventoryPlayer inventoryPlayer, final IInterfaceHost te) {
super(new ContainerInterface(inventoryPlayer, te));
this.ySize = 256;
}
@Override
public void initGui() {
super.initGui();
this.addLabel();
}
@Override
protected void addButtons() {
this.priority = new GuiTabButton(this.guiLeft + 154, this.guiTop, 2 + 4 * 16, GuiText.Priority.getLocal(), this.itemRender);
@@ -59,13 +67,22 @@ public class GuiInterface extends GuiUpgradeable {
this.BlockMode = new GuiImgButton(this.guiLeft - 18, this.guiTop + 8, Settings.BLOCK, YesNo.NO);
this.buttonList.add(this.BlockMode);
this.UnlockMode = new GuiImgButton(this.guiLeft - 18,this.guiTop + 26 ,Settings.UNLOCK, LockCraftingMode.NONE);
this.UnlockMode = new GuiImgButton(this.guiLeft - 18, this.guiTop + 26, Settings.UNLOCK, LockCraftingMode.NONE);
this.buttonList.add(this.UnlockMode);
this.interfaceMode = new GuiToggleButton(this.guiLeft - 18, this.guiTop + 44, 84, 85, GuiText.InterfaceTerminal.getLocal(), GuiText.InterfaceTerminalHint.getLocal());
this.buttonList.add(this.interfaceMode);
}
protected void addLabel() {
if (lockReason != null) {
labelList.remove(this.lockReason);
}
this.lockReason = new GuiImgLabel(this.fontRenderer, guiLeft + 40, guiTop + 12, Settings.UNLOCK, LockCraftingMode.NONE);
this.lockReason.setVisibility(false);
labelList.add(lockReason);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
if (this.BlockMode != null) {
@@ -74,6 +91,15 @@ public class GuiInterface extends GuiUpgradeable {
if (this.UnlockMode != null) {
this.UnlockMode.set(((ContainerInterface) this.cvb).getUnlockMode());
if (this.lockReason != null) {
if (this.UnlockMode.getCurrentValue() == LockCraftingMode.NONE) {
this.lockReason.setVisibility(false);
} else {
this.lockReason.setVisibility(true);
this.lockReason.set(((ContainerInterface) this.cvb).getCraftingLockedReason());
}
}
}
if (this.interfaceMode != null) {
@@ -31,6 +31,7 @@ import appeng.client.gui.widgets.MEGuiTooltipTextField;
import appeng.client.me.ClientDCInternalInv;
import appeng.client.me.SlotDisconnected;
import appeng.container.implementations.ContainerInterfaceTerminal;
import appeng.container.implementations.ContainerWirelessInterfaceTerminal;
import appeng.container.slot.AppEngSlot;
import appeng.core.AEConfig;
import appeng.core.AppEng;
@@ -39,6 +40,7 @@ import appeng.core.localization.GuiText;
import appeng.core.localization.PlayerMessages;
import appeng.helpers.DualityInterface;
import appeng.helpers.PatternHelper;
import appeng.helpers.WirelessTerminalGuiObject;
import appeng.parts.reporting.PartInterfaceTerminal;
import appeng.util.BlockPosUtils;
import appeng.util.Platform;
@@ -67,9 +69,10 @@ import static appeng.helpers.ItemStackHelper.stackFromNBT;
public class GuiInterfaceTerminal extends AEBaseGui {
private static final int OFFSET_X = 21;
protected static final int OFFSET_X = 21;
protected final GuiText guiTitle;
private static final int MAGIC_HEIGHT_NUMBER = 52 + 99;
private static final String MOLECULAR_ASSEMBLER = "molecular assembler";
private static final String MOLECULAR_ASSEMBLER = "tile.appliedenergistics2.molecular_assembler";
private final boolean jeiEnabled;
private final int jeiButtonPadding;
@@ -121,6 +124,29 @@ public class GuiInterfaceTerminal extends AEBaseGui {
guiButtonHideFull = new GuiImgButton(0, 0, Settings.ACTIONS, null);
guiButtonBrokenRecipes = new GuiImgButton(0, 0, Settings.ACTIONS, null);
terminalStyleBox = new GuiImgButton(0, 0, Settings.TERMINAL_STYLE, null);
guiTitle = GuiText.InterfaceTerminal;
}
public GuiInterfaceTerminal(final InventoryPlayer inventoryPlayer, final WirelessTerminalGuiObject guiObject) {
super(new ContainerWirelessInterfaceTerminal(inventoryPlayer, guiObject));
final GuiScrollbar scrollbar = new GuiScrollbar();
this.setScrollBar(scrollbar);
this.xSize = 208;
this.ySize = 255;
this.jeiEnabled = Platform.isModLoaded("jei");
this.jeiButtonPadding = jeiEnabled ? 22 : 0;
searchFieldInputs = createTextField(86, 12, ButtonToolTips.SearchFieldInputs.getLocal());
searchFieldOutputs = createTextField(86, 12, ButtonToolTips.SearchFieldOutputs.getLocal());
searchFieldNames = createTextField(71, 12, ButtonToolTips.SearchFieldNames.getLocal());
searchFieldNames.setFocused(true);
guiButtonAssemblersOnly = new GuiImgButton(0, 0, Settings.ACTIONS, null);
guiButtonHideFull = new GuiImgButton(0, 0, Settings.ACTIONS, null);
guiButtonBrokenRecipes = new GuiImgButton(0, 0, Settings.ACTIONS, null);
terminalStyleBox = new GuiImgButton(0, 0, Settings.TERMINAL_STYLE, null);
guiTitle = GuiText.WirelessTerminal;
}
private MEGuiTooltipTextField createTextField(final int width, final int height, final String tooltip) {
@@ -199,7 +225,7 @@ public class GuiInterfaceTerminal extends AEBaseGui {
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.fontRenderer.drawString(this.getGuiDisplayName(GuiText.InterfaceTerminal.getLocal()), OFFSET_X + 2, 6, 4210752);
this.fontRenderer.drawString(this.getGuiDisplayName(guiTitle.getLocal()), OFFSET_X + 2, 6, 4210752);
this.fontRenderer.drawString(GuiText.inventory.getLocal(), OFFSET_X + 2, this.ySize - 96, 4210752);
final int currentScroll = this.getScrollBar().getCurrentScroll();
@@ -536,7 +562,8 @@ public class GuiInterfaceTerminal extends AEBaseGui {
continue;
}
// Exit if molecular assembler filter is on and this is not a molecular assembler
if (onlyMolecularAssemblers && !entry.getName().toLowerCase().contains(MOLECULAR_ASSEMBLER)) {
// Forge documantation said unlocalized name shouldn't be use for logic, so we might need a better way......
if (onlyMolecularAssemblers && !entry.getUnlocalizedName().equals(MOLECULAR_ASSEMBLER)) {
cachedSearch.remove(entry);
continue;
}
@@ -20,13 +20,14 @@ package appeng.client.gui.implementations;
import appeng.api.implementations.guiobjects.IPortableCell;
import appeng.container.implementations.ContainerMEPortableCell;
import net.minecraft.entity.player.InventoryPlayer;
public class GuiMEPortableCell extends GuiMEMonitorable {
public GuiMEPortableCell(final InventoryPlayer inventoryPlayer, final IPortableCell te) {
super(inventoryPlayer, te);
super(inventoryPlayer, te, new ContainerMEPortableCell(inventoryPlayer, te));
}
@Override
@@ -0,0 +1,18 @@
package appeng.client.gui.implementations;
import appeng.helpers.WirelessTerminalGuiObject;
import net.minecraft.client.gui.Gui;
import net.minecraft.entity.player.InventoryPlayer;
public class GuiWirelessInterfaceTerminal extends GuiInterfaceTerminal {
public GuiWirelessInterfaceTerminal(InventoryPlayer inventoryPlayer, final WirelessTerminalGuiObject te) {
super(inventoryPlayer, te);
}
@Override
public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY) {
this.bindTexture("guis/wirelessupgrades.png");
Gui.drawModalRectWithCustomSizedTexture(offsetX + 189, offsetY + 165, 0, 0, 32, 32, 32, 32);
super.drawBG(offsetX, offsetY, mouseX, mouseY);
}
}
@@ -1,13 +1,14 @@
package appeng.client.gui.widgets;
import appeng.container.interfaces.ISpecialSlotIngredient;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
public abstract class GuiCustomSlot extends Gui implements ITooltip {
public abstract class GuiCustomSlot extends Gui implements ITooltip, ISpecialSlotIngredient {
protected final int x;
protected final int y;
protected final int id;
@@ -68,4 +69,9 @@ public abstract class GuiCustomSlot extends Gui implements ITooltip {
return true;
}
@Override
public Object getIngredient() {
return null;
}
}
@@ -345,7 +345,7 @@ public class GuiImgButton extends GuiButton implements ITooltip {
this.fillVar = fillVar;
}
private static final class EnumPair {
public static final class EnumPair {
final Enum setting;
final Enum value;
@@ -0,0 +1,142 @@
package appeng.client.gui.widgets;
import appeng.api.config.LockCraftingMode;
import appeng.api.config.Settings;
import appeng.core.localization.GuiText;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiLabel;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.translation.I18n;
import java.util.HashMap;
import java.util.Map;
public class GuiImgLabel extends GuiLabel implements ITooltip {
public GuiImgLabel(FontRenderer fontRendererObj, final int x, final int y, final Enum idx, final Enum val) {
super(fontRendererObj, 0, x, y, 16, 16, 0);
this.currentValue = val;
this.labelSetting = idx;
this.fontRenderer = fontRendererObj;
if (appearances == null) {
appearances = new HashMap<>();
registerApp(10, Settings.UNLOCK, LockCraftingMode.NONE, GuiText.NoneLock, null, 0x00FF00);
registerApp(9, Settings.UNLOCK, LockCraftingMode.LOCK_WHILE_LOW, GuiText.CraftingLock, GuiText.LowRedstoneLock, 0xFF0000);
registerApp(9, Settings.UNLOCK, LockCraftingMode.LOCK_WHILE_HIGH, GuiText.CraftingLock, GuiText.HighRedstoneLock, 0xFF0000);
registerApp(9, Settings.UNLOCK, LockCraftingMode.LOCK_UNTIL_PULSE, GuiText.CraftingLock, GuiText.UntilPulseUnlock, 0xFF0000);
registerApp(9, Settings.UNLOCK, LockCraftingMode.LOCK_UNTIL_RESULT, GuiText.CraftingLock, GuiText.ResultLock, 0xFF0000);
}
}
private final Enum labelSetting;
private Enum currentValue;
private static Map<GuiImgButton.EnumPair, LabelAppearance> appearances;
private final FontRenderer fontRenderer;
public void setVisibility(final boolean vis) {
this.visible = vis;
}
@Override
public void drawLabel(Minecraft mc, int mouseX, int mouseY) {
if (this.visible) {
final int iconIndex = this.getIconIndex();
if (iconIndex == -1) {
return;
}
mc.renderEngine.bindTexture(new ResourceLocation("appliedenergistics2", "textures/guis/states.png"));
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
final int uv_y = (int) Math.floor(iconIndex / 16);
final int uv_x = iconIndex - uv_y * 16;
this.drawTexturedModalRect(this.x, this.y, uv_x * 16, uv_y * 16, 16, 16);
if (labelSetting != null && currentValue != null) {
LabelAppearance labelAppearance = appearances.get(new GuiImgButton.EnumPair(this.labelSetting, this.currentValue));
String translated = I18n.translateToLocal(labelAppearance.displayLabel);
fontRenderer.drawString(translated, x + 16, y + 5, labelAppearance.color);
width = 16 + fontRenderer.getStringWidth(translated);
}
}
}
private int getIconIndex() {
if (this.labelSetting != null && this.currentValue != null) {
final LabelAppearance app = appearances.get(new GuiImgButton.EnumPair(this.labelSetting, this.currentValue));
if (app == null) {
return -1;
}
return app.index;
}
return -1;
}
private void registerApp(final int iconIndex, final Settings setting, final Enum val, final GuiText label, final Object hint, int color) {
final LabelAppearance a = new LabelAppearance();
if (hint != null) {
a.hiddenValue = (String) (hint instanceof String ? hint : ((GuiText) hint).getUnlocalized());
} else {
a.hiddenValue = null;
}
a.index = iconIndex;
a.displayLabel = label.getUnlocalized();
a.color = color;
appearances.put(new GuiImgButton.EnumPair(setting, val), a);
}
@Override
public String getMessage() {
if (labelSetting != null && this.currentValue != null) {
LabelAppearance labelAppearance = appearances.get(new GuiImgButton.EnumPair(this.labelSetting, this.currentValue));
if (labelAppearance == null) {
return "No Such Message";
}
if (labelAppearance.hiddenValue != null) {
return I18n.translateToLocal(labelAppearance.hiddenValue);
}
}
return null;
}
public void set(final Enum e) {
if (this.currentValue != e) {
this.currentValue = e;
}
}
@Override
public int xPos() {
return x;
}
@Override
public int yPos() {
return y;
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public boolean isVisible() {
return visible;
}
private static class LabelAppearance {
public int index;
public String displayLabel;
public String hiddenValue;
public int color;
}
}
@@ -55,6 +55,10 @@ public class ClientDCInternalInv implements Comparable<ClientDCInternalInv> {
return s;
}
public String getUnlocalizedName() {
return this.unlocalizedName;
}
@Override
public int compareTo(@Nonnull final ClientDCInternalInv o) {
return Long.compare(this.sortBy, o.sortBy);
@@ -20,11 +20,13 @@ package appeng.client.me;
import appeng.api.storage.data.IAEFluidStack;
import appeng.container.interfaces.ISpecialSlotIngredient;
import appeng.fluids.container.slots.IMEFluidSlot;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.SlotItemHandler;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nonnull;
@@ -34,7 +36,7 @@ import javax.annotation.Nonnull;
* @version rv6 - 22/05/2018
* @since rv6 22/05/2018
*/
public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot, ISpecialSlotIngredient {
private final InternalFluidSlotME slot;
@@ -95,4 +97,11 @@ public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
public boolean canTakeStack(final EntityPlayer par1EntityPlayer) {
return false;
}
@Nullable
@Override
public Object getIngredient() {
return this.getAEFluidStack() == null ? null : this.getAEFluidStack().getFluidStack();
}
}
@@ -1,7 +1,6 @@
package appeng.client.render.model;
import com.google.common.collect.ImmutableMap;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
@@ -9,9 +8,8 @@ import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.block.model.ItemOverrideList;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.client.model.PerspectiveMapWrapper;
import net.minecraftforge.common.model.TRSRTransformation;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
@@ -24,15 +22,12 @@ class ColorApplicatorBakedModel implements IBakedModel {
private final IBakedModel baseModel;
private final ImmutableMap<ItemCameraTransforms.TransformType, TRSRTransformation> transforms;
private final EnumMap<EnumFacing, List<BakedQuad>> quadsBySide;
private final List<BakedQuad> generalQuads;
ColorApplicatorBakedModel(IBakedModel baseModel, ImmutableMap<ItemCameraTransforms.TransformType, TRSRTransformation> map, TextureAtlasSprite texDark, TextureAtlasSprite texMedium, TextureAtlasSprite texBright) {
ColorApplicatorBakedModel(IBakedModel baseModel, TextureAtlasSprite texDark, TextureAtlasSprite texMedium, TextureAtlasSprite texBright) {
this.baseModel = baseModel;
this.transforms = map;
// Put the tint indices in... Since this is an item model, we are ignoring rand
this.generalQuads = this.fixQuadTint(null, texDark, texMedium, texBright);
@@ -68,7 +63,7 @@ class ColorApplicatorBakedModel implements IBakedModel {
}
@Override
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) {
public @NotNull List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) {
if (side == null) {
return this.generalQuads;
}
@@ -91,22 +86,22 @@ class ColorApplicatorBakedModel implements IBakedModel {
}
@Override
public TextureAtlasSprite getParticleTexture() {
public @NotNull TextureAtlasSprite getParticleTexture() {
return this.baseModel.getParticleTexture();
}
@Override
public ItemCameraTransforms getItemCameraTransforms() {
public @NotNull ItemCameraTransforms getItemCameraTransforms() {
return this.baseModel.getItemCameraTransforms();
}
@Override
public ItemOverrideList getOverrides() {
public @NotNull ItemOverrideList getOverrides() {
return this.baseModel.getOverrides();
}
@Override
public Pair<? extends IBakedModel, Matrix4f> handlePerspective(ItemCameraTransforms.TransformType type) {
return PerspectiveMapWrapper.handlePerspective(this, this.transforms, type);
public @NotNull Pair<? extends IBakedModel, Matrix4f> handlePerspective(@NotNull ItemCameraTransforms.TransformType type) {
return this.baseModel.handlePerspective(type);
}
}
@@ -55,7 +55,7 @@ public class ColorApplicatorModel implements IModel {
ImmutableMap<ItemCameraTransforms.TransformType, TRSRTransformation> map = PerspectiveMapWrapper.getTransforms(state);
return new ColorApplicatorBakedModel(baseModel, map, texDark, texMedium, texBright);
return new ColorApplicatorBakedModel(baseModel, texDark, texMedium, texBright);
}
private IBakedModel getBaseModel(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) {
@@ -399,9 +399,17 @@ public abstract class AEBaseContainer extends Container {
return ItemStack.EMPTY; // don't insert duplicate encoded patterns to interfaces
}
int maxSize = Math.min(tis.getMaxStackSize(), d.getSlotStackLimit());
final int maxSize;
if (d instanceof SlotOversized slotOversized) {
maxSize = slotOversized.getSlotStackLimit();
} else {
maxSize = Math.min(tis.getMaxStackSize(), d.getSlotStackLimit());
}
int placeAble = maxSize - t.getCount();
if (placeAble <= 0) {
continue;
}
if (tis.getCount() < placeAble) {
placeAble = tis.getCount();
@@ -953,9 +961,13 @@ public abstract class AEBaseContainer extends Container {
@Override
public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, @NotNull EntityPlayer player) {
if (slotId >= 0 && clickTypeIn == ClickType.PICKUP) {
if (slotId >= 0) {
final var slot = this.getSlot(slotId);
if (slot instanceof AppEngSlot appEngSlot) {
if (slot instanceof SlotDisabled) {
return ItemStack.EMPTY;
}
if (slot instanceof AppEngSlot appEngSlot && clickTypeIn == ClickType.PICKUP) {
var slotStack = slot.getStack();
var draggedStack = this.invPlayer.getItemStack();
@@ -45,6 +45,9 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona
@GuiSync(8)
public YesNo iTermMode = YesNo.YES;
@GuiSync(9)
public LockCraftingMode lockReason = LockCraftingMode.NONE;
public ContainerInterface(final InventoryPlayer ip, final IInterfaceHost te) {
super(ip, te.getInterfaceDuality().getHost());
@@ -94,6 +97,10 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona
patternExpansions = getPatternUpgrades();
this.myDuality.dropExcessPatterns();
}
if (Platform.isServer()){
lockReason = myDuality.getCraftingLockedReason();
}
super.detectAndSendChanges();
}
@@ -134,4 +141,8 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona
public int getPatternUpgrades() {
return this.myDuality.getInstalledUpgrades(Upgrades.PATTERN_EXPANSION);
}
public LockCraftingMode getCraftingLockedReason() {
return lockReason;
}
}
@@ -34,6 +34,7 @@ import appeng.core.sync.packets.PacketInventoryAction;
import appeng.helpers.DualityInterface;
import appeng.helpers.IInterfaceHost;
import appeng.helpers.InventoryAction;
import appeng.helpers.WirelessTerminalGuiObject;
import appeng.items.misc.ItemEncodedPattern;
import appeng.parts.misc.PartInterface;
import appeng.parts.reporting.PartInterfaceTerminal;
@@ -65,7 +66,7 @@ import java.util.Map.Entry;
import static appeng.helpers.ItemStackHelper.stackWriteToNBT;
public final class ContainerInterfaceTerminal extends AEBaseContainer {
public class ContainerInterfaceTerminal extends AEBaseContainer {
/**
* this stuff is all server side..
@@ -87,6 +88,21 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer {
this.bindPlayerInventory(ip, 0, 0);
}
public ContainerInterfaceTerminal(final InventoryPlayer ip, final WirelessTerminalGuiObject guiObject, boolean bindInventory) {
super(ip, guiObject);
if (Platform.isServer()) {
IGridNode node = guiObject.getActionableNode();
if (node != null && node.isActive()) {
this.grid = node.getGrid();
}
}
if (bindInventory) {
this.bindPlayerInventory(ip, 0, 0);
}
}
@Override
public void detectAndSendChanges() {
if (Platform.isClient()) {
@@ -185,14 +201,16 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer {
final AppEngSlot playerSlot;
try {
playerSlot = (AppEngSlot) this.inventorySlots.get(slot);
} catch (IndexOutOfBoundsException ignored) { return; }
} catch (IndexOutOfBoundsException ignored) {
return;
}
if (!playerSlot.isPlayerSide() || !playerSlot.getHasStack()) return;
var itemStack = playerSlot.getStack();
if (!itemStack.isEmpty()) {
var handler = new WrapperFilteredItemHandler(
new WrapperRangeItemHandler(inv.server, 0, 9 * (inv.numUpgrades + 1)), new PatternSlotFilter());
new WrapperRangeItemHandler(inv.server, 0, 9 * (inv.numUpgrades + 1)), new PatternSlotFilter());
playerSlot.putStack(ItemHandlerHelper.insertItem(handler, itemStack, false));
detectAndSendChanges();
}
@@ -388,7 +406,7 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer {
if (slot instanceof SlotDisconnected slotDisconnected && !slot.getHasStack()) {
// Signal the server to move the pattern.
var packet = new PacketInventoryAction(InventoryAction.PLACE_SINGLE,
playerAppEngSlot.slotNumber, slotDisconnected.getSlot().getId());
playerAppEngSlot.slotNumber, slotDisconnected.getSlot().getId());
NetworkHandler.instance().sendToServer(packet);
@@ -0,0 +1,198 @@
package appeng.container.implementations;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.implementations.IUpgradeableCellContainer;
import appeng.api.networking.security.IActionHost;
import appeng.container.interfaces.IInventorySlotAware;
import appeng.container.slot.SlotRestrictedInput;
import appeng.core.AEConfig;
import appeng.core.localization.PlayerMessages;
import appeng.helpers.WirelessTerminalGuiObject;
import appeng.parts.automation.StackUpgradeInventory;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.Platform;
import appeng.util.inv.IAEAppEngInventory;
import appeng.util.inv.InvOperation;
import baubles.api.BaublesApi;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ClickType;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.items.IItemHandler;
import org.jetbrains.annotations.NotNull;
public class ContainerWirelessInterfaceTerminal extends ContainerInterfaceTerminal implements IInventorySlotAware, IUpgradeableCellContainer, IAEAppEngInventory {
private final WirelessTerminalGuiObject wirelessTerminalGUIObject;
private final int slot;
private double powerMultiplier = 0.5;
private int ticks = 0;
protected AppEngInternalInventory upgrades;
protected SlotRestrictedInput magnetSlot;
public ContainerWirelessInterfaceTerminal(InventoryPlayer ip, WirelessTerminalGuiObject guiObject) {
super(ip, guiObject,false);
if (guiObject != null) {
final int slotIndex = guiObject.getInventorySlot();
if (!guiObject.isBaubleSlot()) {
this.lockPlayerInventorySlot(slotIndex);
}
this.slot = slotIndex;
} else {
this.lockPlayerInventorySlot(ip.currentItem);
this.slot = -1;
}
this.bindPlayerInventory(ip,0,0);
this.wirelessTerminalGUIObject = guiObject;
upgrades = new StackUpgradeInventory(wirelessTerminalGUIObject.getItemStack(), this, 2);
this.loadFromNBT();
setupUpgrades();
}
@Override
public void detectAndSendChanges() {
if (Platform.isServer()) {
final ItemStack currentItem;
if (wirelessTerminalGUIObject.isBaubleSlot()) {
currentItem = BaublesApi.getBaublesHandler(this.getPlayerInv().player).getStackInSlot(this.slot);
} else {
currentItem = this.slot < 0 ? this.getPlayerInv().getCurrentItem() : this.getPlayerInv().getStackInSlot(this.slot);
}
if (currentItem.isEmpty()) {
this.setValidContainer(false);
} else if (!this.wirelessTerminalGUIObject.getItemStack().isEmpty() && currentItem != this.wirelessTerminalGUIObject.getItemStack()) {
if (ItemStack.areItemsEqual(this.wirelessTerminalGUIObject.getItemStack(), currentItem)) {
if (wirelessTerminalGUIObject.isBaubleSlot()) {
BaublesApi.getBaublesHandler(this.getPlayerInv().player).setStackInSlot(this.slot, this.wirelessTerminalGUIObject.getItemStack());
} else {
this.getPlayerInv().setInventorySlotContents(this.slot, this.wirelessTerminalGUIObject.getItemStack());
}
} else {
this.setValidContainer(false);
}
}
// drain 1 ae t
this.ticks++;
if (this.ticks > 10) {
double ext = this.wirelessTerminalGUIObject.extractAEPower(this.getPowerMultiplier() * this.ticks, Actionable.MODULATE, PowerMultiplier.CONFIG);
if (ext < this.getPowerMultiplier() * this.ticks) {
if (Platform.isServer() && this.isValidContainer()) {
this.getPlayerInv().player.sendMessage(PlayerMessages.DeviceNotPowered.get());
}
this.setValidContainer(false);
}
this.ticks = 0;
}
if (!this.wirelessTerminalGUIObject.rangeCheck()) {
if (Platform.isServer() && this.isValidContainer()) {
this.getPlayerInv().player.sendMessage(PlayerMessages.OutOfRange.get());
}
this.setValidContainer(false);
} else {
this.setPowerMultiplier(AEConfig.instance().wireless_getDrainRate(this.wirelessTerminalGUIObject.getRange()));
}
super.detectAndSendChanges();
}
}
@Override
public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, @NotNull EntityPlayer player) {
if (slotId >= 0 && slotId < this.inventorySlots.size()) {
if (clickTypeIn == ClickType.PICKUP && dragType == 1) {
if (this.inventorySlots.get(slotId) == magnetSlot) {
ItemStack itemStack = magnetSlot.getStack();
if (!magnetSlot.getStack().isEmpty()) {
NBTTagCompound tag = itemStack.getTagCompound();
if (tag == null) {
tag = new NBTTagCompound();
}
if (tag.hasKey("enabled")) {
boolean e = tag.getBoolean("enabled");
tag.setBoolean("enabled", !e);
} else {
tag.setBoolean("enabled", false);
}
magnetSlot.getStack().setTagCompound(tag);
magnetSlot.onSlotChanged();
return ItemStack.EMPTY;
}
}
}
}
return super.slotClick(slotId, dragType, clickTypeIn, player);
}
private double getPowerMultiplier() {
return this.powerMultiplier;
}
void setPowerMultiplier(final double powerMultiplier) {
this.powerMultiplier = powerMultiplier;
}
@Override
protected IActionHost getActionHost() {
return wirelessTerminalGUIObject;
}
@Override
public int getInventorySlot() {
return wirelessTerminalGUIObject.getInventorySlot();
}
@Override
public boolean isBaubleSlot() {
return wirelessTerminalGUIObject.isBaubleSlot();
}
@Override
public int availableUpgrades() {
return 1;
}
@Override
public void setupUpgrades() {
if (wirelessTerminalGUIObject != null) {
for (int upgradeSlot = 0; upgradeSlot < availableUpgrades(); upgradeSlot++) {
this.magnetSlot = new SlotRestrictedInput(SlotRestrictedInput.PlacableItemType.UPGRADES, upgrades, upgradeSlot, 183, -1 + upgradeSlot * 18, this.getInventoryPlayer());
this.magnetSlot.setNotDraggable();
this.addSlotToContainer(magnetSlot);
}
}
}
private void loadFromNBT() {
NBTTagCompound data = wirelessTerminalGUIObject.getItemStack().getTagCompound();
if (data != null) {
upgrades.readFromNBT(wirelessTerminalGUIObject.getItemStack().getTagCompound().getCompoundTag("upgrades"));
}
}
@Override
public void saveChanges() {
if (Platform.isServer()) {
NBTTagCompound tag = new NBTTagCompound();
this.upgrades.writeToNBT(tag, "upgrades");
this.wirelessTerminalGUIObject.saveChanges(tag);
}
}
@Override
public void onChangeInventory(IItemHandler inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack) {
}
}
@@ -0,0 +1,10 @@
package appeng.container.interfaces;
import javax.annotation.Nullable;
public interface ISpecialSlotIngredient {
@Nullable
Object getIngredient();
}
@@ -445,6 +445,7 @@ final class Registration {
});
}
items.wirelessFluidTerminal().maybeItem().ifPresent(terminal -> registries.wireless().registerWirelessHandler((IWirelessTermHandler) terminal));
items.wirelessInterfaceTerminal().maybeItem().ifPresent(terminal -> registries.wireless().registerWirelessHandler((IWirelessTermHandler) terminal));
// Charge Rates
items.chargedStaff().maybeItem().ifPresent(chargedStaff -> registries.charger().addChargeRate(chargedStaff, 320d));
@@ -13,6 +13,7 @@ import appeng.api.storage.data.IItemList;
import appeng.api.util.IClientHelper;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
import appeng.core.localization.Tooltips;
import appeng.fluids.items.FluidDummyItem;
import appeng.fluids.util.AEFluidStack;
import appeng.util.ReadableNumberConverter;
@@ -44,10 +45,9 @@ public class ApiClientHelper implements IClientHelper {
final ICellInventory<?> cellInventory = handler.getCellInv();
if (cellInventory != null) {
lines.add(cellInventory.getUsedBytes() + " " + GuiText.Of.getLocal() + ' ' + cellInventory.getTotalBytes() + ' ' + GuiText.BytesUsed.getLocal());
lines.add(Tooltips.bytesUsed(cellInventory.getUsedBytes(),cellInventory.getTotalBytes()).getFormattedText());
lines.add(cellInventory.getStoredItemTypes() + " " + GuiText.Of.getLocal() + ' ' + cellInventory.getTotalItemTypes() + ' ' + GuiText.Types
.getLocal());
lines.add(Tooltips.typesUsed(cellInventory.getStoredItemTypes(),cellInventory.getTotalItemTypes()).getFormattedText());
}
IItemList<?> itemList = cellInventory.getChannel().createList();
@@ -80,6 +80,7 @@ public final class ApiItems implements IItems {
private final IItemDefinition wirelessTerminal;
private final IItemDefinition wirelessCraftingTerminal;
private final IItemDefinition wirelessPatternTerminal;
private final IItemDefinition wirelessInterfaceTerminal;
private final IItemDefinition wirelessFluidTerminal;
private final IItemDefinition biometricCard;
private final IItemDefinition chargedStaff;
@@ -184,6 +185,7 @@ public final class ApiItems implements IItems {
this.wirelessCraftingTerminal = powerTools.item("wireless_crafting_terminal", ToolWirelessCraftingTerminal::new).addFeatures(AEFeature.WIRELESS_CRAFTING_TERMINAL).build();
this.wirelessPatternTerminal = powerTools.item("wireless_pattern_terminal", ToolWirelessPatternTerminal::new).addFeatures(AEFeature.WIRELESS_PATTERN_TERMINAL).build();
this.wirelessFluidTerminal = powerTools.item("wireless_fluid_terminal", ToolWirelessFluidTerminal::new).addFeatures(AEFeature.WIRELESS_FLUID_TERMINAL).build();
this.wirelessInterfaceTerminal = powerTools.item("wireless_interface_terminal",ToolWirelessInterfaceTerminal::new).addFeatures(AEFeature.WIRELESS_INTERFACE_TERMINAL).build();
this.chargedStaff = powerTools.item("charged_staff", ToolChargedStaff::new).addFeatures(AEFeature.CHARGED_STAFF).build();
this.massCannon = powerTools.item("matter_cannon", ToolMatterCannon::new)
@@ -365,6 +367,11 @@ public final class ApiItems implements IItems {
return wirelessPatternTerminal;
}
@Override
public IItemDefinition wirelessInterfaceTerminal() {
return wirelessInterfaceTerminal;
}
@Override
public IItemDefinition biometricCard() {
return this.biometricCard;
@@ -67,6 +67,7 @@ public enum AEFeature {
WIRELESS_CRAFTING_TERMINAL("WirelessCraftingTerminal", Constants.CATEGORY_TOOLS),
WIRELESS_PATTERN_TERMINAL("WirelessPatternTerminal", Constants.CATEGORY_TOOLS),
WIRELESS_FLUID_TERMINAL("WirelessFluidTerminal", Constants.CATEGORY_TOOLS),
WIRELESS_INTERFACE_TERMINAL("WirelessInterfaceTerminal", Constants.CATEGORY_TOOLS),
COLOR_APPLICATOR("ColorApplicator", Constants.CATEGORY_TOOLS),
METEORITE_COMPASS("MeteoriteCompass", Constants.CATEGORY_TOOLS),
@@ -37,6 +37,7 @@ import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.oredict.OreDictionary;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -277,4 +278,9 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry {
private void addNewAttunement(final IItemDefinition definition, final TunnelType type) {
definition.maybeStack(1).ifPresent(definitionStack -> this.addNewAttunement(definitionStack, type));
}
@Override
public TunnelType registerTunnelType(@NotNull String enumName, @NotNull ItemStack partStack) {
return TunnelType.registerTunnelType(enumName, partStack);
}
}
@@ -27,6 +27,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -58,8 +59,8 @@ public class InscriberRecipe implements IInscriberRecipe {
this.inputs.addAll(inputs);
this.output = output;
this.maybeTop = top;
this.maybeBot = bot;
this.maybeTop = top == null || top.isEmpty() ? Collections.emptyList() : top;
this.maybeBot = bot == null || bot.isEmpty() ? Collections.emptyList() : bot;
this.type = type;
}
@@ -129,6 +130,4 @@ public class InscriberRecipe implements IInscriberRecipe {
result = 31 * result + this.type.hashCode();
return result;
}
}
@@ -19,6 +19,8 @@
package appeng.core.localization;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.util.text.translation.I18n;
@@ -207,7 +209,20 @@ public enum GuiText {
// Used in Crafting Toasts
CraftingToastDone,
CraftingToastCancelled;
CraftingToastCancelled,
//Used in Lock Crafting,
CraftingLock,
NoneLock,
LowRedstoneLock,
HighRedstoneLock,
ResultLock,
UntilPulseUnlock,
// Used in Annihilation Planes
CanBeEnchanted,
IncreasedEnergyUseFromEnchants,
Deprecated;
private final String root;
@@ -223,6 +238,10 @@ public enum GuiText {
return I18n.translateToLocal(this.getUnlocalized());
}
public ITextComponent getLocalizedWithArgs(Object... args) {
return new TextComponentTranslation(this.getUnlocalized(), args);
}
public String getUnlocalized() {
return this.root + '.' + this;
}
@@ -0,0 +1,203 @@
package appeng.core.localization;
import appeng.api.config.PowerUnits;
import com.github.bsideup.jabel.Desugar;
import net.minecraft.util.text.*;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.util.Arrays;
/**
* Static utilities for constructing tooltips in various places.
*/
public final class Tooltips {
private static final char SEP;
static {
var format = (DecimalFormat) DecimalFormat.getInstance();
var symbols = format.getDecimalFormatSymbols();
SEP = symbols.getDecimalSeparator();
}
public static final Style UNIT_TEXT = new Style().setColor(TextFormatting.YELLOW).setItalic(false);
public static final Style NORMAL_TOOLTIP_TEXT = new Style().setColor(TextFormatting.GRAY).setItalic(false);
public static final Style NUMBER_TEXT = new Style().setColor(TextFormatting.LIGHT_PURPLE).setItalic(false);
public static final String[] units = new String[] { "k", "M", "G", "T", "P", "E" };
public static final long[] DECIMAL_NUMS = new long[] { 1000L, 1000_000L, 1000_000_000L, 1000_000_000_000L,
1000_000_000_000_000L,
1000_000_000_000_000_000L };
public static ITextComponent of(ITextComponent... components) {
ITextComponent s = new TextComponentString("");
for (var c : components) {
s = s.appendSibling(c);
}
return s;
}
public static ITextComponent of(String s) {
return new TextComponentString(s);
}
public static ITextComponent ofPercent(double percent) {
return ofPercent(percent,true);
}
public static ITextComponent ofPercent(double percent, boolean oneIsGreen) {
return new TextComponentString(MessageFormat.format("{0,number,#.##%}", percent))
.setStyle(colorFromRatio(percent, oneIsGreen));
}
public static ITextComponent of(PowerUnits pU) {
return new TextComponentTranslation(pU.unlocalizedName).setStyle(UNIT_TEXT);
}
public static ITextComponent ofNumber(double number, double max) {
MaxedAmount amount = getMaxedAmount(number, max);
return ofNumber(amount);
}
public static ITextComponent of(GuiText guiText, Object... args) {
return of(guiText, NORMAL_TOOLTIP_TEXT, args);
}
public static ITextComponent of(GuiText guiText, Style style, Object... args) {
if (args.length > 0 && args[0] instanceof Integer) {
return guiText.getLocalizedWithArgs(Arrays.stream(args).map((o) -> ofUnformattedNumber((Integer) o)).toArray()).createCopy()
.setStyle(style);
} else if (args.length > 0 && args[0] instanceof Long) {
return guiText.getLocalizedWithArgs(Arrays.stream(args).map((o) -> ofUnformattedNumber((Long) o)).toArray()).createCopy()
.setStyle(style);
}
return guiText.getLocalizedWithArgs(args).createCopy().setStyle(style);
}
public static ITextComponent ofUnformattedNumber(long number) {
return new TextComponentString(String.valueOf(number)).setStyle(NUMBER_TEXT);
}
public static ITextComponent ofUnformattedNumberWithRatioColor(long number, double ratio, boolean oneIsGreen) {
return new TextComponentString(String.valueOf(number)).setStyle(colorFromRatio(ratio, oneIsGreen));
}
private static ITextComponent ofNumber(MaxedAmount number) {
boolean numberUnit = !number.digit().equals("0");
return new TextComponentString(number.digit() + (numberUnit ? number.unit() : "")).setStyle(NUMBER_TEXT)
.appendSibling(new TextComponentString("/")
.setStyle(NORMAL_TOOLTIP_TEXT))
.appendText(number.maxDigit() + number.unit()).setStyle(NUMBER_TEXT);
}
@Desugar
public record MaxedAmount(String digit, String maxDigit, String unit) {
}
@Desugar
public record Amount(String digit, String unit) {
}
public static Style colorFromRatio(double ratio, boolean oneIsGreen) {
double p = ratio;
if (!oneIsGreen) {
p = 1 - p;
}
TextFormatting colorCode = getColorCode(p);
return new Style().setItalic(false).setColor(colorCode);
}
public static String getAmount(double amount, long num) {
double fract = amount / num;
String returned;
if (fract < 10) {
returned = String.format("%.3f", fract);
} else if (fract < 100) {
returned = String.format("%.2f", fract);
} else {
returned = String.format("%.1f", fract);
}
while (returned.endsWith("0")) {
returned = returned.substring(0, returned.length() - 1);
}
if (returned.endsWith(String.valueOf(SEP))) {
returned = returned.substring(0, returned.length() - 1);
}
return returned;
}
public static Amount getAmount(double amount) {
if (amount < 10000) {
return new Amount(getAmount(amount, 1), "");
} else {
int i = 0;
while (amount / DECIMAL_NUMS[i] >= 1000) {
i++;
}
return new Amount(getAmount(amount, DECIMAL_NUMS[i]), units[i]);
}
}
public static MaxedAmount getMaxedAmount(double amount, double max) {
if (max < 10000) {
return new MaxedAmount(getAmount(amount, 1), getAmount(max, 1), "");
} else {
int i = 0;
while (max / DECIMAL_NUMS[i] >= 1000) {
i++;
}
return new MaxedAmount(getAmount(amount, DECIMAL_NUMS[i]), getAmount(max, DECIMAL_NUMS[i]), units[i]);
}
}
private static TextFormatting getColorCode(double p) {
if (p < 0.33) {
return TextFormatting.RED;
} else if (p < 0.66) {
return TextFormatting.YELLOW;
} else {
return TextFormatting.GREEN;
}
}
public static ITextComponent energyStorageComponent(double energy, double max) {
return Tooltips.of(
Tooltips.of(GuiText.StoredEnergy.getLocal()),
Tooltips.of(": "),
Tooltips.ofNumber(energy, max),
Tooltips.of(" "),
Tooltips.of(PowerUnits.AE),
Tooltips.of(" ("),
Tooltips.ofPercent(energy / max),
Tooltips.of(")"));
}
public static ITextComponent bytesUsed(long bytes, long max) {
return of(
Tooltips.of(
ofUnformattedNumberWithRatioColor(bytes, (double) bytes / max, false),
of(" "),
of(GuiText.Of),
of(" "),
ofUnformattedNumber(max),
of(" "),
of(GuiText.BytesUsed)));
}
public static ITextComponent typesUsed(long types, long max) {
return Tooltips.of(
ofUnformattedNumberWithRatioColor(types, (double) types / max, false),
of(" "),
of(GuiText.Of),
of(" "),
ofUnformattedNumber(max),
of(" "),
of(GuiText.Types));
}
}
@@ -41,7 +41,9 @@ public enum WailaText {
Showing,
Contains,
Channels;
Channels,
EnchantedWith,
IdentityDeprecated;
private final String root;
+3 -12
View File
@@ -58,20 +58,11 @@ import appeng.parts.automation.PartFormationPlane;
import appeng.parts.automation.PartLevelEmitter;
import appeng.parts.misc.PartOreDicStorageBus;
import appeng.parts.misc.PartStorageBus;
import appeng.parts.reporting.PartCraftingTerminal;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import appeng.parts.reporting.PartFluidInterfaceConfigurationTerminal;
import appeng.parts.reporting.PartInterfaceConfigurationTerminal;
import appeng.parts.reporting.PartInterfaceTerminal;
import appeng.parts.reporting.PartPatternTerminal;
import appeng.parts.reporting.*;
import appeng.tile.crafting.TileCraftingTile;
import appeng.tile.crafting.TileMolecularAssembler;
import appeng.tile.grindstone.TileGrinder;
import appeng.tile.misc.TileCellWorkbench;
import appeng.tile.misc.TileCondenser;
import appeng.tile.misc.TileInscriber;
import appeng.tile.misc.TileSecurityStation;
import appeng.tile.misc.TileVibrationChamber;
import appeng.tile.misc.*;
import appeng.tile.networking.TileWireless;
import appeng.tile.qnb.TileQuantumBridge;
import appeng.tile.spatial.TileSpatialIOPort;
@@ -114,7 +105,7 @@ public enum GuiBridge implements IGuiHandler {
GUI_WIRELESS_CRAFTING_TERMINAL(ContainerWirelessCraftingTerminal.class, WirelessTerminalGuiObject.class, GuiHostType.ITEM, null),
GUI_WIRELESS_PATTERN_TERMINAL(ContainerWirelessPatternTerminal.class, WirelessTerminalGuiObject.class, GuiHostType.ITEM, null),
GUI_WIRELESS_FLUID_TERMINAL(ContainerWirelessFluidTerminal.class, WirelessTerminalGuiObject.class, GuiHostType.ITEM, null),
GUI_WIRELESS_INTERFACE_TERMINAL(ContainerWirelessInterfaceTerminal.class, WirelessTerminalGuiObject.class, GuiHostType.ITEM, null),
GUI_NETWORK_STATUS(ContainerNetworkStatus.class, INetworkTool.class, GuiHostType.ITEM, null),
@@ -99,4 +99,9 @@ public class GuiFluidSlot extends GuiCustomSlot implements IJEITargetSlot {
return this.getFluidStack() == null;
}
@Override
public Object getIngredient() {
return this.getFluidStack() == null ? null : this.getFluidStack().getFluidStack();
}
}
@@ -147,4 +147,9 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip {
}
}
@Override
public Object getIngredient() {
return this.getFluidStack() == null ? null : this.getFluidStack().getFluidStack();
}
}
@@ -224,8 +224,8 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
this.items.setInternal(this.gridProxy.getStorage().getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)));
this.fluids.setInternal(this.gridProxy.getStorage().getInventory(AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class)));
} catch (final GridAccessException gae) {
this.items.setInternal(new NullInventory<IAEItemStack>());
this.fluids.setInternal(new NullInventory<IAEFluidStack>());
this.items.setInternal(new NullInventory<>());
this.fluids.setInternal(new NullInventory<>());
}
this.notifyNeighbors();
@@ -491,6 +491,16 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
onFluidInventoryChanged(inv, slot, null, null, null);
}
@Override
public void onFluidInventoryChanged(final IAEFluidTank inventory, FluidStack added, FluidStack removed) {
if (inventory == this.tanks) {
if (added != null) {
iHost.onStackReturnNetwork(AEFluidStack.fromFluidStack(added));
}
this.saveChanges();
}
}
@Override
public void onFluidInventoryChanged(final IAEFluidTank inventory, final int slot, InvOperation operation, FluidStack added, FluidStack removed) {
if (this.isWorking == slot) {
@@ -194,10 +194,11 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
IItemList<IAEFluidStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class).createList();
for (IFluidTankProperties tankProperty : tankProperties) {
if (this.mode == StorageFilter.EXTRACTABLE_ONLY && this.fluidHandler.drain(1, false) == null) {
var contents = tankProperty.getContents();
if (this.mode == StorageFilter.EXTRACTABLE_ONLY && this.fluidHandler.drain(contents, false) == null) {
continue;
}
currentlyOnStorage.add(AEFluidStack.fromFluidStack(tankProperty.getContents()));
currentlyOnStorage.add(AEFluidStack.fromFluidStack(contents));
}
for (final IAEFluidStack is : currentlyCached) {
@@ -14,7 +14,7 @@ import java.util.Objects;
public class AEFluidInventory implements IAEFluidTank {
private final IAEFluidStack[] fluids;
private final IAEFluidInventory handler;
protected final IAEFluidInventory handler;
private int capacity;
private IFluidTankProperties[] props = null;
@@ -35,8 +35,16 @@ public class AENetworkFluidInventory extends AEFluidInventory {
if (overflow != null && overflow.getStackSize() == originAmt) {
return super.fill(fluid, doFill);
} else if (overflow != null) {
if (doFill) {
FluidStack added = fluid.copy();
added.amount = (int) (fluid.amount - overflow.getStackSize());
this.handler.onFluidInventoryChanged(this, added, null);
}
return (int) (originAmt - overflow.getStackSize());
} else {
if (doFill) {
this.handler.onFluidInventoryChanged(this, fluid, null);
}
return originAmt;
}
} else {
@@ -28,4 +28,8 @@ public interface IAEFluidInventory {
default void onFluidInventoryChanged(final IAEFluidTank inv, final int slot, InvOperation operation, FluidStack added, FluidStack removed) {
}
default void onFluidInventoryChanged(final IAEFluidTank inv, FluidStack added, FluidStack removed) {
}
}
@@ -40,6 +40,7 @@ import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartHost;
import appeng.api.storage.*;
import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
@@ -55,6 +56,7 @@ import appeng.core.AELog;
import appeng.core.settings.TickRates;
import appeng.me.GridAccessException;
import appeng.me.helpers.AENetworkProxy;
import appeng.me.helpers.IGridProxyable;
import appeng.me.helpers.MachineSource;
import appeng.me.storage.MEMonitorIInventory;
import appeng.me.storage.MEMonitorPassThrough;
@@ -64,7 +66,6 @@ import appeng.parts.automation.UpgradeInventory;
import appeng.parts.misc.PartInterface;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.AppEngInternalOversizedInventory;
import appeng.tile.inventory.AppEngNetworkInventory;
import appeng.tile.networking.TileCableBus;
import appeng.util.ConfigManager;
@@ -78,6 +79,7 @@ import com.google.common.primitives.Ints;
import de.ellpeck.actuallyadditions.api.tile.IPhantomTile;
import gregtech.api.block.machines.BlockMachine;
import gregtech.api.metatileentity.MetaTileEntity;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Items;
@@ -95,7 +97,6 @@ import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.RangedWrapper;
import javax.annotation.Nullable;
import java.util.*;
@@ -128,7 +129,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private final Accessor accessor = new Accessor();
private boolean hasConfig = false;
private int priority;
private List<ICraftingPatternDetails> craftingList = null;
private Set<ICraftingPatternDetails> craftingList = null;
private List<ItemStack> waitingToSend = null;
private IMEInventory<IAEItemStack> destination;
private int isWorking = -1;
@@ -452,10 +453,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
this.addToCraftingList(this.patterns.getStackInSlot(x));
}
}
try {
this.gridProxy.getGrid().postEvent(new MENetworkCraftingPatternChange(this, this.gridProxy.getNode()));
} catch (GridAccessException e) {
e.printStackTrace();
if (newPattern || removed) {
try {
this.gridProxy.getGrid().postEvent(new MENetworkCraftingPatternChange(this, this.gridProxy.getNode()));
} catch (GridAccessException e) {
e.printStackTrace();
}
}
}
@@ -545,7 +549,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
if (details != null) {
if (this.craftingList == null) {
this.craftingList = new ArrayList<>();
this.craftingList = new ObjectOpenHashSet<>();
}
this.craftingList.add(details);
@@ -878,7 +882,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
private InventoryAdaptor getAdaptor(final int slot) {
return new AdaptorItemHandler(new RangedWrapper(this.storage, slot, slot + 1));
return new AdaptorItemHandler(((AppEngNetworkInventory) this.storage).getBufferWrapper(slot));
}
private boolean handleCrafting(final int x, final InventoryAdaptor d, final IAEItemStack itemStack) {
@@ -959,7 +963,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
@Override
public appeng.api.util.IConfigManager getConfigManager() {
public IConfigManager getConfigManager() {
return this.cm;
}
@@ -1022,58 +1026,64 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
for (final EnumFacing s : visitedFaces) {
final TileEntity te = w.getTileEntity(tile.getPos().offset(s));
if (te instanceof IInterfaceHost || (te instanceof TileCableBus && ((TileCableBus) te).getPart(s.getOpposite()) instanceof PartInterface)) {
if (te == null) {
visitedFaces.remove(s);
continue;
}
var mon = te.getCapability(Capabilities.STORAGE_MONITORABLE_ACCESSOR, s.getOpposite());
if (mon != null) {
visitedFaces.remove(s);
try {
IInterfaceHost targetTE;
if (te instanceof IInterfaceHost) {
targetTE = (IInterfaceHost) te;
IGridProxyable proxyable;
if (te instanceof IGridProxyable) {
proxyable = (IGridProxyable) te;
} else if (te instanceof IPartHost partHost) {
proxyable = (IGridProxyable) partHost.getPart(s.getOpposite());
} else {
targetTE = (IInterfaceHost) ((TileCableBus) te).getPart(s.getOpposite());
continue;
}
if (targetTE.getInterfaceDuality().sameGrid(this.gridProxy.getGrid())) {
if (proxyable.getProxy().getGrid() == this.gridProxy.getGrid()) {
continue;
} else {
IStorageMonitorableAccessor mon = te.getCapability(Capabilities.STORAGE_MONITORABLE_ACCESSOR, s.getOpposite());
if (mon != null) {
IStorageMonitorable sm = mon.getInventory(this.mySource);
if (sm != null && Platform.canAccess(targetTE.getInterfaceDuality().gridProxy, this.mySource)) {
if (this.isBlocking() && sm.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)).getStorageList().size() > 0) {
}
IStorageMonitorable sm = mon.getInventory(this.mySource);
if (sm != null && Platform.canAccess(proxyable.getProxy(), this.mySource)) {
if (this.isBlocking() && !sm.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)).getStorageList().isEmpty()) {
continue;
} else {
IMEMonitor<IAEItemStack> inv = sm.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class));
var allItemsCanBeInserted = true;
for (int x = 0; x < table.getSizeInventory(); x++) {
final ItemStack is = table.getStackInSlot(x);
if (is.isEmpty()) {
continue;
} else {
IMEMonitor<IAEItemStack> inv = sm.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class));
var allItemsCanBeInserted = true;
for (int x = 0; x < table.getSizeInventory(); x++) {
final ItemStack is = table.getStackInSlot(x);
if (is.isEmpty()) {
continue;
}
IAEItemStack result = inv.injectItems(AEItemStack.fromItemStack(is), Actionable.SIMULATE, this.mySource);
if (result != null) {
allItemsCanBeInserted = false;
break;
}
}
if (!allItemsCanBeInserted) {
continue;
}
this.visitedFaces.clear();
for (int x = 0; x < table.getSizeInventory(); x++) {
final ItemStack is = table.getStackInSlot(x);
if (!is.isEmpty()) {
addToSendListFacing(is, s);
}
}
onPushPatternSuccess(patternDetails);
pushItemsOut(s);
return true;
}
IAEItemStack result = inv.injectItems(AEItemStack.fromItemStack(is), Actionable.SIMULATE, this.mySource);
if (result != null) {
allItemsCanBeInserted = false;
break;
}
}
if (!allItemsCanBeInserted) {
continue;
}
this.visitedFaces.clear();
for (int x = 0; x < table.getSizeInventory(); x++) {
final ItemStack is = table.getStackInSlot(x);
if (!is.isEmpty()) {
addToSendListFacing(is, s);
}
}
onPushPatternSuccess(patternDetails);
pushItemsOut(s);
return true;
}
}
} catch (final GridAccessException e) {
@@ -1156,7 +1166,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
case LOCK_UNTIL_RESULT -> {
unlockEvent = UnlockCraftingEvent.RESULT;
unlockStack = pattern.getPrimaryOutput();
unlockStack = pattern.getPrimaryOutput().copy();
saveChanges();
}
}
@@ -1165,7 +1175,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
/**
* Gets if the crafting lock is in effect and why.
*
* @return null if the lock isn't in effect
* @return {@link LockCraftingMode#NONE} if the lock isn't in effect
*/
public LockCraftingMode getCraftingLockedReason() {
var lockMode = cm.getSetting(Settings.UNLOCK);
@@ -1450,7 +1460,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
if (what.getItem() != Items.AIR) {
return what.getItem().getItemStackDisplayName(what);
/* getTranslationKey() and getUnlocalizedNameInefficiently() have different return values in some mod
* For the Thermal Expansion
* getTranslationKey() returns complete key ending with ".name".
* getUnlocalizedNameInefficiently() returns localized name
* Because CoFH Core overrides method getTranslationKey()
*/
return what.getItem().getTranslationKey(what);
}
final Item item = Item.getItemFromBlock(directedBlock);
@@ -1515,7 +1531,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
/**
* @return Null if {@linkplain #getCraftingLockedReason()} is not {@link LockCraftingMode#LOCK_UNTIL_RESULT}.
*/
@org.jetbrains.annotations.Nullable
@Nullable
public IAEItemStack getUnlockStack() {
return unlockStack;
}
@@ -1529,7 +1545,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
// Actually an error state...
AELog.error("MEInterface was waiting for RESULT, but no result was set");
unlockEvent = null;
} else if (unlockStack.getItem().equals(stack.getItem())) {
} else if (unlockStack.isSameType(stack)) {
var remainingAmount = unlockStack.getStackSize() - stack.getStackSize();
if (remainingAmount <= 0) {
unlockEvent = null;
@@ -44,9 +44,11 @@ import mezz.jei.api.recipe.VanillaRecipeCategoryUid;
import mezz.jei.config.Constants;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.NonNullList;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -185,8 +187,17 @@ public class JEIPlugin implements IModPlugin {
private void registerFacadeRecipe(IDefinitions definitions, IModRegistry registry) {
Optional<Item> itemFacade = definitions.items().facade().maybeItem();
Optional<ItemStack> cableAnchor = definitions.parts().cableAnchor().maybeStack(1);
if (itemFacade.isPresent() && cableAnchor.isPresent() && AEConfig.instance().isFeatureEnabled(AEFeature.ENABLE_FACADE_CRAFTING)) {
registry.addRecipeRegistryPlugin(new FacadeRegistryPlugin((ItemFacade) itemFacade.get(), cableAnchor.get()));
if (itemFacade.isPresent()) {
var facade = (ItemFacade)itemFacade.get();
if (cableAnchor.isPresent() && AEConfig.instance().isFeatureEnabled(AEFeature.ENABLE_FACADE_CRAFTING)){
registry.addRecipeRegistryPlugin(new FacadeRegistryPlugin(facade, cableAnchor.get()));
}
// Hide facades from JEI/HEI except for the first found.
var list = NonNullList.<ItemStack>create();
facade.getSubItems(Objects.requireNonNull(facade.getCreativeTab()), list);
list.stream().skip(1)
.forEach(registry.getJeiHelpers().getIngredientBlacklist()::addIngredientToBlacklist);
}
}
@@ -69,8 +69,9 @@ public final class PartWailaDataProvider implements IWailaDataProvider {
final IPartWailaDataProvider powerState = new PowerStateWailaDataProvider();
final IPartWailaDataProvider p2pState = new P2PStateWailaDataProvider();
final IPartWailaDataProvider partStack = new PartStackWailaDataProvider();
final IPartWailaDataProvider annihilationPlane = new AnnihilationPlaneDataProvider();
this.providers = Lists.newArrayList(channel, storageMonitor, powerState, partStack, p2pState);
this.providers = Lists.newArrayList(channel, storageMonitor, powerState, partStack, p2pState, annihilationPlane);
}
@Override
@@ -0,0 +1,47 @@
package appeng.integration.modules.waila.part;
import appeng.api.parts.IPart;
import appeng.core.localization.WailaText;
import appeng.parts.automation.PartAnnihilationPlane;
import appeng.parts.automation.PartIdentityAnnihilationPlane;
import appeng.util.EnchantmentUtil;
import mcp.mobius.waila.api.IWailaConfigHandler;
import mcp.mobius.waila.api.IWailaDataAccessor;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.List;
import java.util.Map;
public class AnnihilationPlaneDataProvider extends BasePartWailaDataProvider {
@Override
public List<String> getWailaBody(IPart part, List<String> currentToolTip, IWailaDataAccessor accessor, IWailaConfigHandler config) {
if (part instanceof PartIdentityAnnihilationPlane) {
currentToolTip.add(WailaText.IdentityDeprecated.getLocal());
} else if (part instanceof PartAnnihilationPlane plane) {
NBTTagCompound nbtData = accessor.getNBTData();
Map<Enchantment, Integer> enchantments = EnchantmentUtil.getEnchantments(nbtData);
if (!enchantments.isEmpty()) {
currentToolTip.add(WailaText.EnchantedWith.getLocal());
for (var enchantment : enchantments.keySet()) {
currentToolTip.add(enchantment.getTranslatedName(enchantments.get(enchantment)));
}
}
}
return currentToolTip;
}
@Override
public NBTTagCompound getNBTData(EntityPlayerMP player, IPart part, TileEntity te, NBTTagCompound tag, World world, BlockPos pos) {
if (part instanceof PartAnnihilationPlane plane) {
plane.writeEnchantments(tag);
}
return tag;
}
}
@@ -57,11 +57,6 @@ public abstract class AEBaseItem extends Item {
}
}
@Override
public boolean isBookEnchantable(final ItemStack itemstack1, final ItemStack itemstack2) {
return false;
}
@SideOnly(Side.CLIENT)
protected void addCheckedInformation(final ItemStack stack, final World world, final List<String> lines, final ITooltipFlag advancedTooltips) {
super.addInformation(stack, world, lines, advancedTooltips);
+52 -1
View File
@@ -30,8 +30,12 @@ import appeng.core.localization.GuiText;
import appeng.items.AEBaseItem;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Enchantments;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
@@ -133,10 +137,20 @@ public final class ItemPart extends AEBaseItem implements IPartItem, IItemGroup
@Override
public EnumActionResult onItemUse(final EntityPlayer player, final World w, final BlockPos pos, final EnumHand hand, final EnumFacing side, final float hitX, final float hitY, final float hitZ) {
if (this.getTypeByStack(player.getHeldItem(hand)) == PartType.INVALID_TYPE) {
ItemStack heldItem = player.getHeldItem(hand);
PartType typeByStack = getTypeByStack(heldItem);
if (typeByStack == PartType.INVALID_TYPE) {
return EnumActionResult.FAIL;
}
if (player.isSneaking() && typeByStack == PartType.IDENTITY_ANNIHILATION_PLANE) {
ItemStack newPlane = new ItemStack(this, heldItem.getCount(), PartType.ANNIHILATION_PLANE.getBaseDamage());
newPlane.addEnchantment(Enchantments.SILK_TOUCH,1);
player.setHeldItem(hand, newPlane);
return EnumActionResult.SUCCESS;
}
return AEApi.instance().partHelper().placeBus(player.getHeldItem(hand), pos, side, player, hand, w);
}
@@ -178,6 +192,43 @@ public final class ItemPart extends AEBaseItem implements IPartItem, IItemGroup
}
}
@Override
protected void addCheckedInformation(ItemStack stack, World world, List<String> lines, ITooltipFlag advancedTooltips) {
if (getTypeByStack(stack) == PartType.ANNIHILATION_PLANE) {
var enchantments = EnchantmentHelper.getEnchantments(stack);
if (enchantments.isEmpty()) {
lines.add(GuiText.CanBeEnchanted.getLocal());
}
else {
lines.add(GuiText.IncreasedEnergyUseFromEnchants.getLocal());
}
}
if (getTypeByStack(stack) == PartType.IDENTITY_ANNIHILATION_PLANE) {
lines.add(GuiText.Deprecated.getLocal());
}
}
@Override
public int getItemEnchantability() {
return 10;
}
@Override
public boolean isEnchantable(ItemStack stack) {
return getTypeByStack(stack) == PartType.ANNIHILATION_PLANE;
}
@Override
public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
return enchantment == Enchantments.UNBREAKING || enchantment == Enchantments.FORTUNE || enchantment == Enchantments.SILK_TOUCH || enchantment == Enchantments.EFFICIENCY;
}
@Override
public boolean isBookEnchantable(ItemStack stack, ItemStack book) {
return getTypeByStack(stack) == PartType.ANNIHILATION_PLANE;
}
@Nonnull
public PartType getTypeByStack(final ItemStack is) {
Preconditions.checkNotNull(is);
@@ -8,7 +8,8 @@ public enum Terminal {
WIRELESS_TERMINAL(AEApi.instance().definitions().items().wirelessTerminal(), GuiBridge.GUI_WIRELESS_TERM),
WIRELESS_CRAFTING_TERMINAL(AEApi.instance().definitions().items().wirelessCraftingTerminal(), GuiBridge.GUI_WIRELESS_CRAFTING_TERMINAL),
WIRELESS_PATTERN_TERMINAL(AEApi.instance().definitions().items().wirelessPatternTerminal(), GuiBridge.GUI_WIRELESS_PATTERN_TERMINAL),
WIRELESS_FLUID_TERMINAL(AEApi.instance().definitions().items().wirelessFluidTerminal(), GuiBridge.GUI_WIRELESS_FLUID_TERMINAL);
WIRELESS_FLUID_TERMINAL(AEApi.instance().definitions().items().wirelessFluidTerminal(), GuiBridge.GUI_WIRELESS_FLUID_TERMINAL),
WIRELESS_INTERFACE_TERMINAL(AEApi.instance().definitions().items().wirelessInterfaceTerminal(),GuiBridge.GUI_WIRELESS_INTERFACE_TERMINAL);
final GuiBridge bridge;
final IItemDefinition itemDefinition;
@@ -0,0 +1,18 @@
package appeng.items.tools.powered;
import appeng.api.AEApi;
import appeng.core.sync.GuiBridge;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.network.IGuiHandler;
public class ToolWirelessInterfaceTerminal extends ToolWirelessTerminal {
@Override
public boolean canHandle(ItemStack is) {
return AEApi.instance().definitions().items().wirelessInterfaceTerminal().isSameAs(is);
}
@Override
public IGuiHandler getGuiHandler(ItemStack is) {
return GuiBridge.GUI_WIRELESS_INTERFACE_TERMINAL;
}
}
@@ -20,13 +20,7 @@ package appeng.items.tools.powered;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.FuzzyMode;
import appeng.api.config.Settings;
import appeng.api.config.SortDir;
import appeng.api.config.SortOrder;
import appeng.api.config.Upgrades;
import appeng.api.config.ViewItems;
import appeng.api.config.*;
import appeng.api.features.IWirelessTermHandler;
import appeng.api.util.IConfigManager;
import appeng.core.AEConfig;
@@ -51,7 +45,7 @@ import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.translation.I18n;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.Optional;
@@ -95,9 +89,9 @@ public class ToolWirelessTerminal extends AEBasePoweredItem implements IWireless
final String encKey = tag.getString("encryptionKey");
if (encKey == null || encKey.isEmpty()) {
lines.add(GuiText.Unlinked.getLocal());
lines.add(TextFormatting.RED + GuiText.Unlinked.getLocal());
} else {
lines.add(GuiText.Linked.getLocal());
lines.add(TextFormatting.GREEN + GuiText.Linked.getLocal());
}
}
} else {
@@ -21,9 +21,8 @@ package appeng.items.tools.powered.powersink;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.PowerUnits;
import appeng.api.implementations.items.IAEItemPowerStorage;
import appeng.core.localization.GuiText;
import appeng.core.localization.Tooltips;
import appeng.items.AEBaseItem;
import appeng.util.Platform;
import net.minecraft.client.util.ITooltipFlag;
@@ -36,7 +35,6 @@ import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.text.MessageFormat;
import java.util.List;
@@ -65,10 +63,8 @@ public abstract class AEBasePoweredItem extends AEBaseItem implements IAEItemPow
internalCurrentPower = tag.getDouble(CURRENT_POWER_NBT_KEY);
}
final double percent = internalCurrentPower / internalMaxPower;
lines.add(GuiText.StoredEnergy.getLocal() + ':' + MessageFormat.format(" {0,number,#} ", internalCurrentPower) + Platform
.gui_localize(PowerUnits.AE.unlocalizedName) + " - " + MessageFormat.format(" {0,number,#.##%} ", percent));
lines.add(
Tooltips.energyStorageComponent(internalCurrentPower, internalMaxPower).getFormattedText());
}
@Override
@@ -24,6 +24,7 @@ import appeng.api.config.Actionable;
import appeng.api.config.SecurityPermissions;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.security.ISecurityGrid;
import appeng.api.storage.IMEInventoryHandler;
@@ -31,7 +32,6 @@ import appeng.api.storage.IStorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.me.cache.SecurityCache;
import net.minecraft.network.Packet;
import java.util.*;
@@ -45,6 +45,7 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
private static int currentPass = 0;
private final IStorageChannel<T> myChannel;
private final SecurityCache security;
private final NavigableMap<Integer, List<IMEInventoryHandler<T>>> craftingPriorityInventory;
private final NavigableMap<Integer, List<IMEInventoryHandler<T>>> priorityInventory;
private final NavigableMap<Integer, List<IMEInventoryHandler<T>>> stickyPriorityInventory;
private int myPass = 0;
@@ -54,19 +55,22 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
this.security = security;
this.priorityInventory = new TreeMap<>(PRIORITY_SORTER);
this.stickyPriorityInventory = new TreeMap<>(PRIORITY_SORTER);
this.craftingPriorityInventory = new TreeMap<>(PRIORITY_SORTER);
}
public void addNewStorage(final IMEInventoryHandler<T> h) {
final int priority = h.getPriority();
final List<IMEInventoryHandler<T>> list;
if (h.isSticky()) {
list = this.stickyPriorityInventory.computeIfAbsent(priority, $ -> new ArrayList<>());
final NavigableMap<Integer, List<IMEInventoryHandler<T>>> list;
if (h instanceof ICraftingGrid) {
list = this.craftingPriorityInventory;
} else if (h.isSticky()) {
list = this.stickyPriorityInventory;
} else {
list = this.priorityInventory.computeIfAbsent(priority, $ -> new ArrayList<>());
list = this.priorityInventory;
}
list.add(h);
list.computeIfAbsent(priority, $ -> new ArrayList<>()).add(h);
}
@Override
@@ -80,7 +84,26 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
return input;
}
// First pass. Check if the crafting grid is awaiting the input.
for (final List<IMEInventoryHandler<T>> invList : this.craftingPriorityInventory.values()) {
Iterator<IMEInventoryHandler<T>> ii = invList.iterator();
while (ii.hasNext() && input != null) {
final IMEInventoryHandler<T> inv = ii.next();
if (inv.canAccept(input) && (inv.isPrioritized(input) || inv.extractItems(input, Actionable.SIMULATE, src) != null)) {
input = inv.injectItems(input, type, src);
}
}
}
// If everything got stored in the crafting storage, no need to continue.
if (input == null) {
this.surface(this, type);
return input;
}
boolean stickyInventoryFound = false;
// For this pass we do return input if the item is able to go into a sticky inventory. We NEVER want to try and
// insert the item into a non-sticky inventory if it could already go into a sticky inventory.
for (final List<IMEInventoryHandler<T>> stickyInvList : this.stickyPriorityInventory.values()) {
@@ -113,7 +136,6 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
// We need to ignore prioritized inventories in the second pass. If they were not able to store everything
// during the first pass, they will do so in the second, but as this is stateless we will just report twice
// the amount of storable items.
// ignores craftingcache on the second pass.
ii = invList.iterator();
while (ii.hasNext() && input != null) {
final IMEInventoryHandler<T> inv = ii.next();
@@ -236,22 +258,21 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
return out;
}
out = iterateInventories(out, priorityInventory);
out = iterateInventories(out, stickyPriorityInventory);
iterateInventories(out, priorityInventory);
iterateInventories(out, stickyPriorityInventory);
iterateInventories(out, craftingPriorityInventory);
this.surface(this, Actionable.SIMULATE);
return out;
}
private IItemList<T> iterateInventories(IItemList<T> out, final NavigableMap<Integer, List<IMEInventoryHandler<T>>> map) {
private void iterateInventories(IItemList<T> out, final NavigableMap<Integer, List<IMEInventoryHandler<T>>> map) {
for (final List<IMEInventoryHandler<T>> i : map.values()) {
for (final IMEInventoryHandler<T> j : i) {
out = j.getAvailableItems(out);
j.getAvailableItems(out);
}
}
return out;
}
private boolean diveIteration(final NetworkInventoryHandler<T> networkInventoryHandler, final Actionable type) {
+24 -4
View File
@@ -41,6 +41,7 @@ import appeng.items.tools.quartz.ToolQuartzCuttingKnife;
import appeng.me.helpers.AENetworkProxy;
import appeng.me.helpers.IGridProxyable;
import appeng.parts.automation.PartLevelEmitter;
import appeng.parts.misc.PartOreDicStorageBus;
import appeng.parts.networking.PartCable;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.util.Platform;
@@ -315,6 +316,10 @@ public abstract class AEBasePart implements IPart, IGridProxyable, IActionHost,
if (cm != null) {
cm.readFromNBT(compound);
}
if (this instanceof PartOreDicStorageBus oreDicStorageBus) {
oreDicStorageBus.saveOreMatch(compound.getString("oreMatch"));
}
}
if (this instanceof IPriorityHost) {
@@ -359,14 +364,29 @@ public abstract class AEBasePart implements IPart, IGridProxyable, IActionHost,
* @param from source of settings
* @return compound of source
*/
@Deprecated
protected NBTTagCompound downloadSettings(final SettingsFrom from) {
final NBTTagCompound output = new NBTTagCompound();
NBTTagCompound compound = downloadSettings(from, new NBTTagCompound());
return compound.isEmpty() ? null : compound;
}
/**
* Exports settings for attaching it to a memory card or item stack.
*
* @param from The purpose to export settings for.
* @param output The tag to write the settings to.
*/
protected NBTTagCompound downloadSettings(final SettingsFrom from, final NBTTagCompound output) {
final IConfigManager cm = this.getConfigManager();
if (cm != null) {
cm.writeToNBT(output);
}
if (this instanceof PartOreDicStorageBus oreDicStorageBus) {
output.setString("oreMatch", oreDicStorageBus.getOreExp());
}
if (this instanceof IPriorityHost) {
final IPriorityHost pHost = (IPriorityHost) this;
output.setInteger("priority", pHost.getPriority());
@@ -392,7 +412,7 @@ public abstract class AEBasePart implements IPart, IGridProxyable, IActionHost,
}
}
return output.isEmpty() ? null : output;
return output;
}
public boolean useStandardMemoryCard() {
@@ -419,8 +439,8 @@ public abstract class AEBasePart implements IPart, IGridProxyable, IActionHost,
final String name = is.getTranslationKey();
if (player.isSneaking()) {
final NBTTagCompound data = this.downloadSettings(SettingsFrom.MEMORY_CARD);
if (data != null) {
final NBTTagCompound data = this.downloadSettings(SettingsFrom.MEMORY_CARD, new NBTTagCompound());
if (!data.isEmpty()) {
memoryCard.setMemoryCardContents(memCardIS, name, data);
memoryCard.notifyUser(player, MemoryCardMessages.SETTINGS_SAVED);
}
@@ -48,16 +48,26 @@ import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import appeng.me.helpers.MachineSource;
import appeng.parts.PartBasicState;
import appeng.util.EnchantmentUtil;
import appeng.util.IWorldCallable;
import appeng.util.Platform;
import appeng.util.SettingsFrom;
import appeng.util.item.AEItemStack;
import com.google.common.collect.Lists;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Enchantments;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
@@ -65,8 +75,14 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.common.util.FakePlayerFactory;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
public class PartAnnihilationPlane extends PartBasicState implements IGridTickable, IWorldCallable<TickRateModulation> {
@@ -82,6 +98,12 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
private boolean isAccepting = true;
private boolean breaking = false;
/**
* Enchantments found on the plane when it was placed will be used to enchant the fake tool used for picking up
* blocks.
*/
private Map<Enchantment, Integer> enchantments = new LinkedHashMap<>();
public PartAnnihilationPlane(final ItemStack is) {
super(is);
}
@@ -92,6 +114,7 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
return this.breakBlock(true);
}
@Override
public void getBoxes(final IPartCollisionHelper bch) {
int minX = 1;
@@ -371,7 +394,7 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
if (hasPower && canStore) {
if (modulate) {
energy.extractAEPower(requiredPower, Actionable.MODULATE, PowerMultiplier.CONFIG);
this.breakBlockAndStoreItems(w, pos);
this.breakBlockAndStoreItems(w, pos, items);
AppEng.proxy.sendToAllNearExcept(null, pos.getX(), pos.getY(), pos.getZ(), 64, w,
new PacketTransitionEffect(pos.getX(), pos.getY(), pos.getZ(), this.getSide(), true));
} else {
@@ -422,14 +445,33 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
}
protected List<ItemStack> obtainBlockDrops(final WorldServer w, final BlockPos pos) {
final ItemStack[] out = Platform.getBlockDrops(w, pos);
return Lists.newArrayList(out);
final FakePlayer fakePlayer = FakePlayerFactory.getMinecraft(w);
final IBlockState state = w.getBlockState(pos);
if (state.getBlock().canSilkHarvest(w, pos, state, fakePlayer) && enchantments.containsKey(Enchantments.SILK_TOUCH)) {
final List<ItemStack> out = new ArrayList<>(1);
final Item item = Item.getItemFromBlock(state.getBlock());
if (item != Items.AIR) {
int meta = 0;
if (item.getHasSubtypes()) {
meta = state.getBlock().getMetaFromState(state);
}
final ItemStack itemstack = new ItemStack(item, 1, meta);
out.add(itemstack);
}
return out;
} else {
final ItemStack[] out = Platform.getBlockDrops(w, pos, enchantments.getOrDefault(Enchantments.FORTUNE, 0));
return Lists.newArrayList(out);
}
}
/**
* Checks if this plane can handle the block at the specific coordinates.
*/
protected float calculateEnergyUsage(final WorldServer w, final BlockPos pos, final List<ItemStack> items) {
boolean useEnergy = true;
final IBlockState state = w.getBlockState(pos);
final float hardness = state.getBlockHardness(w, pos);
@@ -438,7 +480,25 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
requiredEnergy += is.getCount();
}
return requiredEnergy;
if (!enchantments.isEmpty()) {
var efficiencyFactor = 1f;
var efficiencyLevel = 0;
if (enchantments.containsKey(Enchantments.EFFICIENCY)) {
// Reduce total energy usage incurred by other enchantments by 15% per Efficiency level.
efficiencyLevel = enchantments.get(Enchantments.EFFICIENCY);
efficiencyFactor *= Math.pow(0.85, efficiencyLevel);
}
if (enchantments.containsKey(Enchantments.UNBREAKING)) {
// Give plane only a (100 / (level + 1))% chance to use energy.
// This is similar to vanilla Unbreaking behaviour for tools.
int randomNumber = ThreadLocalRandom.current().nextInt(enchantments.get(Enchantments.UNBREAKING) + 1);
useEnergy = randomNumber == 0;
}
var levelSum = enchantments.values().stream().reduce(0, Integer::sum) - efficiencyLevel;
requiredEnergy *= 8 * levelSum * efficiencyFactor;
}
return useEnergy ? requiredEnergy : 0;
}
/**
@@ -447,10 +507,10 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
* It also sets isAccepting to false, if the item can not be stored.
*
* @param itemStacks an array of {@link ItemStack} to test
* @return true, if the network can store at least a single item of all drops or no drops are reported
* @return true, if the network can store all drops or no drops are reported
*/
private boolean canStoreItemStacks(final List<ItemStack> itemStacks) {
boolean canStore = itemStacks.isEmpty();
boolean canStore = true;
try {
final IStorageGrid storage = this.getProxy().getStorage();
@@ -459,8 +519,8 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
final IAEItemStack itemToTest = AEItemStack.fromItemStack(itemStack);
final IAEItemStack overflow = storage.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class))
.injectItems(itemToTest, Actionable.SIMULATE, this.mySrc);
if (overflow == null || itemToTest.getStackSize() > overflow.getStackSize()) {
canStore = true;
if (overflow != null) {
canStore = false;
}
}
} catch (final GridAccessException e) {
@@ -471,16 +531,17 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
return canStore;
}
private void breakBlockAndStoreItems(final WorldServer w, final BlockPos pos) {
w.destroyBlock(pos, true);
private void breakBlockAndStoreItems(final WorldServer w, final BlockPos pos, List<ItemStack> items) {
for (ItemStack item : items) {
Block.spawnAsEntity(w, pos, item);
}
final AxisAlignedBB box = new AxisAlignedBB(pos).grow(0.2);
for (final Object ei : w.getEntitiesWithinAABB(EntityItem.class, box)) {
if (ei instanceof EntityItem) {
final EntityItem entityItem = (EntityItem) ei;
this.storeEntityItem(entityItem);
}
for (EntityItem entityItem : w.getEntitiesWithinAABB(EntityItem.class, box)) {
this.storeEntityItem(entityItem);
}
w.destroyBlock(pos, false);
}
private void refresh() {
@@ -498,4 +559,50 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
return MODELS.getModel(this.getConnections(), this.isPowered(), this.isActive());
}
@Override
protected NBTTagCompound downloadSettings(SettingsFrom from, NBTTagCompound output) {
super.downloadSettings(from, output);
// Save enchants only when the actual plane is dismantled
if (from == SettingsFrom.DISMANTLE_ITEM) {
writeEnchantments(output);
}
return output;
}
@Override
public void uploadSettings(SettingsFrom from, NBTTagCompound output, EntityPlayer player) {
super.uploadSettings(from, output, player);
// Import enchants only when the plan is placed, not from memory cards
if (from == SettingsFrom.DISMANTLE_ITEM) {
readEnchantments(output);
}
}
public void readEnchantments(NBTTagCompound data) {
enchantments = EnchantmentUtil.getEnchantments(data);
EnchantmentHelper.setEnchantments(enchantments, getItemStack());
}
public void writeEnchantments(NBTTagCompound data) {
EnchantmentUtil.setEnchantments(data, enchantments);
}
@Override
public void readFromNBT(NBTTagCompound data) {
super.readFromNBT(data);
readEnchantments(data);
}
@Override
public void writeToNBT(NBTTagCompound data) {
super.writeToNBT(data);
writeEnchantments(data);
}
@Override
public void addToWorld() {
super.addToWorld();
enchantments = EnchantmentHelper.getEnchantments(getItemStack());
}
}
@@ -19,17 +19,20 @@
package appeng.parts.automation;
import appeng.api.parts.IPart;
import appeng.api.AEApi;
import appeng.api.parts.IPartHost;
import appeng.api.parts.IPartModel;
import appeng.api.util.AEPartLocation;
import appeng.items.parts.PartModels;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Enchantments;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.common.util.FakePlayerFactory;
@@ -53,15 +56,6 @@ public class PartIdentityAnnihilationPlane extends PartAnnihilationPlane {
super(is);
}
@Override
protected boolean isAnnihilationPlane(final TileEntity blockTileEntity, final AEPartLocation side) {
if (blockTileEntity instanceof IPartHost) {
final IPart p = ((IPartHost) blockTileEntity).getPart(side);
return p != null && p.getClass() == this.getClass();
}
return false;
}
@Override
protected float calculateEnergyUsage(final WorldServer w, final BlockPos pos, final List<ItemStack> items) {
final float requiredEnergy = super.calculateEnergyUsage(w, pos, items);
@@ -92,6 +86,20 @@ public class PartIdentityAnnihilationPlane extends PartAnnihilationPlane {
}
}
@Override
public boolean onPartShiftActivate(EntityPlayer player, EnumHand hand, Vec3d pos) {
TileEntity tile = getTile();
if (tile instanceof IPartHost host) {
host.removePart(getSide(), false);
ItemStack itemStack = AEApi.instance().definitions().parts().annihilationPlane().maybeStack(1).orElse(ItemStack.EMPTY);
itemStack.addEnchantment(Enchantments.SILK_TOUCH, 1);
host.addPart(itemStack, getSide(), player, hand);
return true;
}
return false;
}
@Override
public IPartModel getStaticModels() {
return MODELS.getModel(this.getConnections(), this.isPowered(), this.isActive());
@@ -299,8 +299,8 @@ public class PartInterface extends PartBasicState implements IGridTickable, ISto
}
@Override
public NBTTagCompound downloadSettings(SettingsFrom from) {
NBTTagCompound output = super.downloadSettings(from);
public NBTTagCompound downloadSettings(SettingsFrom from, NBTTagCompound compound) {
NBTTagCompound output = super.downloadSettings(from, compound);
if (from == SettingsFrom.MEMORY_CARD) {
final IItemHandler inv = this.getInventoryByName("patterns");
if (inv instanceof AppEngInternalInventory) {
@@ -20,12 +20,7 @@ package appeng.parts.p2p;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.config.PowerUnits;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.TunnelType;
import appeng.api.definitions.IParts;
import appeng.api.config.*;
import appeng.api.implementations.items.IMemoryCard;
import appeng.api.implementations.items.MemoryCardMessages;
import appeng.api.networking.events.MENetworkBootingStatusChange;
@@ -185,8 +180,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
}
final TunnelType tt = AEApi.instance().registries().p2pTunnel().getTunnelTypeByItem(is);
if (!is.isEmpty() && is.getItem() instanceof IMemoryCard) {
final IMemoryCard mc = (IMemoryCard) is.getItem();
if (!is.isEmpty() && is.getItem() instanceof IMemoryCard mc) {
final NBTTagCompound data = mc.getData(is);
final ItemStack newType = new ItemStack(data);
@@ -208,8 +202,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
final AEPartLocation dir = this.getHost().addPart(newType, this.getSide(), player, hand);
final IPart newBus = this.getHost().getPart(dir);
if (newBus instanceof PartP2PTunnel) {
final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus;
if (newBus instanceof PartP2PTunnel newTunnel) {
if (pasteAsOutput) {
newTunnel.setOutput(true);
@@ -233,56 +226,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
mc.notifyUser(player, MemoryCardMessages.INVALID_MACHINE);
} else if (tt != null) // attunement
{
final ItemStack newType;
final IParts parts = AEApi.instance().definitions().parts();
switch (tt) {
case LIGHT:
newType = parts.p2PTunnelLight().maybeStack(1).orElse(ItemStack.EMPTY);
break;
case FE_POWER:
newType = parts.p2PTunnelFE().maybeStack(1).orElse(ItemStack.EMPTY);
break;
case GTEU_POWER:
newType = parts.p2PTunnelGTEU().maybeStack(1).orElse(ItemStack.EMPTY);
break;
case FLUID:
newType = parts.p2PTunnelFluids().maybeStack(1).orElse(ItemStack.EMPTY);
break;
case IC2_POWER:
newType = parts.p2PTunnelEU().maybeStack(1).orElse(ItemStack.EMPTY);
break;
case ITEM:
newType = parts.p2PTunnelItems().maybeStack(1).orElse(ItemStack.EMPTY);
break;
case ME:
newType = parts.p2PTunnelME().maybeStack(1).orElse(ItemStack.EMPTY);
break;
case REDSTONE:
newType = parts.p2PTunnelRedstone().maybeStack(1).orElse(ItemStack.EMPTY);
break;
/*
* case COMPUTER_MESSAGE:
* for( ItemStack stack : parts.p2PTunnelOpenComputers().maybeStack( 1 ).asSet() )
* {
* newType = stack;
* }
* break;
*/
default:
newType = ItemStack.EMPTY;
break;
}
final ItemStack newType = tt.getPartItemStack();
if (!newType.isEmpty() && !ItemStack.areItemsEqual(newType, this.getItemStack())) {
final boolean oldOutput = this.isOutput();
@@ -299,8 +243,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
final AEPartLocation dir = this.getHost().addPart(newType, this.getSide(), player, hand);
final IPart newBus = this.getHost().getPart(dir);
if (newBus instanceof PartP2PTunnel) {
final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus;
if (newBus instanceof PartP2PTunnel newTunnel) {
newTunnel.setOutput(oldOutput);
try {
@@ -333,12 +276,11 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
}
final ItemStack is = player.inventory.getCurrentItem();
if (!is.isEmpty() && is.getItem() instanceof IMemoryCard) {
if (!is.isEmpty() && is.getItem() instanceof IMemoryCard mc) {
if (Platform.isClient()) {
return true;
}
final IMemoryCard mc = (IMemoryCard) is.getItem();
final NBTTagCompound data = mc.getData(is);
final short storedFrequency = data.getShort("freq");
@@ -365,8 +307,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
final AEPartLocation dir = this.getHost().addPart(newType, this.getSide(), player, hand);
final IPart newBus = this.getHost().getPart(dir);
if (newBus instanceof PartP2PTunnel) {
final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus;
if (newBus instanceof PartP2PTunnel newTunnel) {
newTunnel.setOutput(false);
newTunnel.getProxy().getP2P().updateFreq(newTunnel, newFreq);
@@ -8,8 +8,10 @@ import appeng.api.storage.IMEInventory;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.util.inv.IAEAppEngInventory;
import appeng.util.inv.InvOperation;
import appeng.util.item.AEItemStack;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.wrapper.RangedWrapper;
import javax.annotation.Nonnull;
import java.util.function.Supplier;
@@ -36,8 +38,16 @@ public class AppEngNetworkInventory extends AppEngInternalOversizedInventory {
if (overflow != null && overflow.getStackSize() == originAmt) {
return super.insertItem(slot, stack, simulate);
} else if (overflow != null) {
if (!simulate) {
ItemStack added = stack.copy();
added.setCount((int) (stack.getCount() - overflow.getStackSize()));
this.getTileEntity().onChangeInventory(this, slot, InvOperation.INSERT, ItemStack.EMPTY, added);
}
return overflow.createItemStack();
} else {
if (!simulate) {
this.getTileEntity().onChangeInventory(this, slot, InvOperation.INSERT, ItemStack.EMPTY, stack);
}
return ItemStack.EMPTY;
}
} else {
@@ -45,4 +55,22 @@ public class AppEngNetworkInventory extends AppEngInternalOversizedInventory {
}
}
@Nonnull
private ItemStack insertToBuffer(int slot, @Nonnull ItemStack stack, boolean simulate) {
return super.insertItem(slot, stack, simulate);
}
public RangedWrapper getBufferWrapper(int selectSlot) {
return new RangedWrapper(this, selectSlot, selectSlot + 1) {
@Override
@Nonnull
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
if (slot == 0) {
return AppEngNetworkInventory.this.insertToBuffer(selectSlot, stack, simulate);
}
return stack;
}
};
}
}
@@ -0,0 +1,74 @@
package appeng.util;
import com.google.common.collect.Maps;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import java.util.HashMap;
import java.util.Map;
public final class EnchantmentUtil {
private EnchantmentUtil() {
}
private static Map<Enchantment, Integer> deserializeEnchantments(NBTTagList tagList) {
Map<Enchantment, Integer> map = Maps.newLinkedHashMap();
for(int i = 0; i < tagList.tagCount(); ++i) {
NBTTagCompound compoundtag = tagList.getCompoundTagAt(i);
Enchantment enchantmentByID = Enchantment.getEnchantmentByID(getEnchantmentId(compoundtag));
if (enchantmentByID != null) {
map.put(enchantmentByID, getEnchantmentLevel(compoundtag));
}
}
return map;
}
private static int getEnchantmentId(NBTTagCompound tagCompound) {
return tagCompound.getInteger("id");
}
private static int getEnchantmentLevel(NBTTagCompound tagCompound) {
return Math.max(0, Math.min(255, tagCompound.getInteger("lvl")));
}
private static NBTTagCompound storeEnchantment(int id, int level) {
NBTTagCompound compoundtag = new NBTTagCompound();
compoundtag.setShort("id",(short) id);
compoundtag.setShort("lvl", ((short) level));
return compoundtag;
}
/**
* Read enchants written using {@link #setEnchantments} or added to an itemstack's tag using normal enchanting.
*/
public static Map<Enchantment, Integer> getEnchantments(NBTTagCompound data) {
if (data.hasKey("Enchantments",9)) {
var list = data.getTagList("Enchantments",10);
var enchants = deserializeEnchantments(list);
if (!enchants.isEmpty()) {
return enchants;
}
}
return new HashMap<>();
}
/**
* Writes a list of enchantments to the given tag the same way as
* {@link EnchantmentHelper#setEnchantments(Map, ItemStack)} would.
*/
public static void setEnchantments(NBTTagCompound tag, Map<Enchantment, Integer> enchantments) {
NBTTagList enchantList = new NBTTagList();
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
Enchantment enchantment = entry.getKey();
if (enchantment == null)
continue;
int level = entry.getValue();
enchantList.appendTag(storeEnchantment(Enchantment.getEnchantmentID(enchantment), level));
}
tag.setTag("Enchantments", enchantList);
}
}
+8 -2
View File
@@ -430,15 +430,21 @@ public class Platform {
}
}
public static ItemStack[] getBlockDrops(final World w, final BlockPos pos) {
return getBlockDrops(w, pos,0);
}
public static ItemStack[] getBlockDrops(final World w, final BlockPos pos, int fortune) {
List<ItemStack> out = new ArrayList<>();
final IBlockState state = w.getBlockState(pos);
if (state != null) {
out = state.getBlock().getDrops(w, pos, state, 0);
out = state.getBlock().getDrops(w, pos, state, fortune);
}
if (out == null) {
if (out == null || out.isEmpty()) {
return new ItemStack[0];
}
return out.toArray(new ItemStack[out.size()]);
@@ -1,3 +1,6 @@
# GUI rendering
public net.minecraft.client.gui.inventory.GuiContainer func_146977_a(Lnet/minecraft/inventory/Slot;)V # drawSlot
public net.minecraft.client.gui.inventory.GuiContainer field_146988_G # dragSplittingButton
public net.minecraft.client.gui.inventory.GuiContainer field_146987_F # dragSplittingLimit
public net.minecraft.client.gui.inventory.GuiContainer field_146995_H # ignoreMouseUp
public net.minecraft.client.gui.GuiTextField func_146188_c(IIII)V # drawSelectionBox
@@ -258,6 +258,15 @@ gui.appliedenergistics2.CraftingToastDone=Crafting Done!
gui.appliedenergistics2.CraftingToastCancelled=Crafting Cancelled!
gui.appliedenergistics2.Sticky=Sticky
gui.appliedenergistics2.FluidTerminal=Fluid Terminal
gui.appliedenergistics2.CraftingLock=Crafting is locked
gui.appliedenergistics2.NoneLock=Crafting is unlocked
gui.appliedenergistics2.HighRedstoneLock=Locked by redstone signal
gui.appliedenergistics2.LowRedstoneLock=Locked by lack of redstone signal
gui.appliedenergistics2.ResultLock=Waiting for pattern output to unlock
gui.appliedenergistics2.UntilPulseUnlock=Waiting for redstone pulse to unlock
gui.appliedenergistics2.CanBeEnchanted=Can be enchanted
gui.appliedenergistics2.IncreasedEnergyUseFromEnchants=Enchants increase energy use
gui.appliedenergistics2.Deprecated=Deprecated
// GUI Tooltips
gui.tooltips.appliedenergistics2.Stash=Store Items
@@ -441,6 +450,8 @@ waila.appliedenergistics2.p2p_input_many_outputs=Linked (Input Side) - §4%d§r
waila.appliedenergistics2.p2p_output_one_input=Linked (Output Side) - 1 Input
waila.appliedenergistics2.p2p_output_many_inputs=Linked (Output Side) - §2%d§r Inputs
waila.appliedenergistics2.P2POutput=Linked (Output Side)
waila.appliedenergistics2.EnchantedWith=Enchanted with:
waila.appliedenergistics2.IdentityDeprecated=Deprecated. Convert with SHIFT + RIGHT-CLICK
// TheOneProbe
theoneprobe.appliedenergistics2.crafting=Crafting: §2%1$s§r
@@ -615,6 +626,7 @@ item.appliedenergistics2.matter_cannon.name=Matter Cannon
item.appliedenergistics2.memory_card.name=Memory Card
item.appliedenergistics2.color_applicator.name=Color Applicator
item.appliedenergistics2.wireless_terminal.name=Wireless Terminal
item.appliedenergistics2.wireless_interface_terminal.name=Wireless Interface Terminal
item.appliedenergistics2.wireless_crafting_terminal.name=Wireless Crafting Terminal
item.appliedenergistics2.wireless_pattern_terminal.name=Wireless Pattern Terminal
item.appliedenergistics2.wireless_fluid_terminal.name=Wireless Fluid Terminal
@@ -697,3 +709,4 @@ key.open_wireless_terminal.desc=Open Wireless Terminal
key.open_wireless_crafting_terminal.desc=Open Wireless Crafting Terminal
key.open_wireless_pattern_terminal.desc=Open Wireless Pattern Terminal
key.open_wireless_fluid_terminal.desc=Open Wireless Fluid Terminal
key.open_wireless_interface_terminal.desc=Open Wireless Interface Terminal
@@ -258,6 +258,15 @@ gui.appliedenergistics2.CraftingToastDone=合成已完成!
gui.appliedenergistics2.CraftingToastCancelled=合成已取消!
gui.appliedenergistics2.Sticky=粘滞
gui.appliedenergistics2.FluidTerminal=流体终端
gui.appliedenergistics2.NoneLock=合成已解锁
gui.appliedenergistics2.CraftingLock=合成已锁定
gui.appliedenergistics2.LowRedstoneLock=由于缺少红石信号而锁定
gui.appliedenergistics2.HighRedstoneLock=由于红石信号而锁定
gui.appliedenergistics2.ResultLock=等待样板输出解锁
gui.appliedenergistics2.UntilPulseUnlock=等待红石脉冲解锁
gui.appliedenergistics2.CanBeEnchanted=可被附魔
gui.appliedenergistics2.IncreasedEnergyUseFromEnchants=附魔会增加能耗
gui.appliedenergistics2.Deprecated=已弃用
// GUI Tooltips
gui.tooltips.appliedenergistics2.Stash=存储物品
@@ -442,6 +451,8 @@ waila.appliedenergistics2.p2p_input_many_outputs=已连接(输入端)- §4%d
waila.appliedenergistics2.p2p_output_one_input=已连接(输出端)- 1输入
waila.appliedenergistics2.p2p_output_many_inputs=已连接(输出端)- §2%d§r输入
waila.appliedenergistics2.P2POutput=已连接(输出端)
waila.appliedenergistics2.EnchantedWith=已附魔:
waila.appliedenergistics2.IdentityDeprecated=已弃用。 使用SHIFT + 右键来转换
// TheOneProbe
theoneprobe.appliedenergistics2.crafting=合成中:§2%1$s§r
@@ -616,6 +627,7 @@ item.appliedenergistics2.matter_cannon.name=物质炮
item.appliedenergistics2.memory_card.name=内存卡
item.appliedenergistics2.color_applicator.name=染色器
item.appliedenergistics2.wireless_terminal.name=无线终端
item.appliedenergistics2.wireless_interface_terminal.name=无线接口终端
item.appliedenergistics2.wireless_crafting_terminal.name=无线合成终端
item.appliedenergistics2.wireless_pattern_terminal.name=无线样板终端
item.appliedenergistics2.wireless_fluid_terminal.name=无线流体终端
@@ -698,3 +710,4 @@ key.open_wireless_terminal.desc=打开无线终端
key.open_wireless_crafting_terminal.desc=打开无线合成终端
key.open_wireless_pattern_terminal.desc=打开无线样板终端
key.open_wireless_fluid_terminal.desc=打开无线流体终端
key.open_wireless_interface_terminal.desc=打开无线接口终端
@@ -1,5 +1,5 @@
{
"parent": "item/generated",
"parent": "appliedenergistics2:item/color_applicator_uncolored",
"textures": {
"layer0": "appliedenergistics2:items/color_applicator",
"layer1": "appliedenergistics2:items/color_applicator_tip_dark",
@@ -1,6 +1,42 @@
{
"parent": "item/generated",
"parent": "item/handheld",
"textures": {
"layer0": "appliedenergistics2:items/color_applicator"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
90,
-55
],
"translation": [
0,
4,
0.5
],
"scale": [
0.85,
0.85,
0.85
]
},
"thirdperson_lefthand": {
"rotation": [
0,
-90,
55
],
"translation": [
0,
4,
0.5
],
"scale": [
0.85,
0.85,
0.85
]
}
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "appliedenergistics2:items/wireless_interface_terminal"
}
}
@@ -1,36 +0,0 @@
{
"conditions": [
{
"type": "forge:and",
"values": [
{
"type": "appliedenergistics2:part_exists",
"part": "part.identity_annihilation_plane"
},
{
"type": "appliedenergistics2:part_exists",
"part": "part.annihilation_plane"
},
{
"type": "appliedenergistics2:material_exists",
"material": "material.fluix_pearl"
}
]
}
],
"result": {
"type": "appliedenergistics2:part",
"part": "part.identity_annihilation_plane"
},
"type": "appliedenergistics2:part_shapeless",
"ingredients": [
{
"type": "appliedenergistics2:part",
"part": "part.annihilation_plane"
},
{
"type": "appliedenergistics2:part",
"part": "material.fluix_pearl"
}
]
}
@@ -0,0 +1,47 @@
{
"conditions": [
{
"type": "forge:and",
"values": [
{
"type": "minecraft:item_exists",
"item": "appliedenergistics2:wireless_interface_terminal"
},
{
"type": "minecraft:item_exists",
"item": "appliedenergistics2:dense_energy_cell"
},
{
"type": "appliedenergistics2:part_exists",
"part": "part.interface_terminal"
},
{
"type": "appliedenergistics2:material_exists",
"material": "material.wireless"
}
]
}
],
"result": {
"item": "appliedenergistics2:wireless_interface_terminal"
},
"type": "forge:ore_shaped",
"pattern": [
"a",
"b",
"c"
],
"key": {
"b": {
"type": "appliedenergistics2:part",
"part": "part.interface_terminal"
},
"c": {
"item": "appliedenergistics2:dense_energy_cell"
},
"a": {
"type": "appliedenergistics2:part",
"part": "material.wireless"
}
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB