diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c7103f7..7dc4a37 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,16 +6,16 @@ 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: Build with Gradle run: ./gradlew build # Ensure your gradlew script is executable - name: Upload Artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: NAE2 path: build/libs/*.jar # Make sure this path matches the location of your build artifacts \ No newline at end of file diff --git a/src/main/java/co/neeve/nae2/common/api/config/WirelessTerminalType.java b/src/main/java/co/neeve/nae2/common/api/config/WirelessTerminalType.java new file mode 100644 index 0000000..89d6af1 --- /dev/null +++ b/src/main/java/co/neeve/nae2/common/api/config/WirelessTerminalType.java @@ -0,0 +1,11 @@ +package co.neeve.nae2.common.api.config; + +public enum WirelessTerminalType { + ITEM, + FLUID, + GAS, + CRAFTING, + PATTERN, + INTERFACE, + FLUID_PATTERN, +} diff --git a/src/main/java/co/neeve/nae2/common/containers/ContainerPatternMultiTool.java b/src/main/java/co/neeve/nae2/common/containers/ContainerPatternMultiTool.java index 001f0be..e489722 100644 --- a/src/main/java/co/neeve/nae2/common/containers/ContainerPatternMultiTool.java +++ b/src/main/java/co/neeve/nae2/common/containers/ContainerPatternMultiTool.java @@ -29,6 +29,7 @@ import co.neeve.nae2.common.slots.SlotPatternMultiToolUpgrade; import com.glodblock.github.common.item.ItemFluidDrop; import com.glodblock.github.common.item.ItemFluidEncodedPattern; +import com.glodblock.github.common.item.fake.FakeItemRegister; import com.google.common.collect.Lists; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.InventoryPlayer; @@ -40,6 +41,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.math.BlockPos; +import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.relauncher.Side; @@ -327,10 +329,10 @@ public void onSlotChange(Slot s) { list.set(idx, data); } else continue; } else if (fluidReplacement && stack.getItem() instanceof ItemFluidDrop) { - var fluidStack = ItemFluidDrop.getFluidStack(stack); + var fluidStack = FakeItemRegister.getStack(stack); // This should never be a crafting pattern. - if (fluidStackIn.isFluidEqual(fluidStack)) { + if (fluidStackIn.isFluidEqual(((FluidStack) fluidStack))) { result = ValidatonResult.OK; } } diff --git a/src/main/java/co/neeve/nae2/common/features/Features.java b/src/main/java/co/neeve/nae2/common/features/Features.java index 03de78d..28b52d6 100644 --- a/src/main/java/co/neeve/nae2/common/features/Features.java +++ b/src/main/java/co/neeve/nae2/common/features/Features.java @@ -41,7 +41,8 @@ public boolean isEnabled() { }, DENSE_CPU_COPROCESSORS("dense.coprocessor"), DENSE_FLUID_CELLS(), - EXPOSER(); + EXPOSER(), + UNIVERSAL_TERMINAL("universalterminal"),; private String[] mixins; private EnumSet subFeatures = null; diff --git a/src/main/java/co/neeve/nae2/common/helpers/UniversalTerminalHelper.java b/src/main/java/co/neeve/nae2/common/helpers/UniversalTerminalHelper.java new file mode 100644 index 0000000..dd84903 --- /dev/null +++ b/src/main/java/co/neeve/nae2/common/helpers/UniversalTerminalHelper.java @@ -0,0 +1,280 @@ +package co.neeve.nae2.common.helpers; + +import appeng.api.AEApi; +import appeng.util.Platform; +import co.neeve.nae2.common.api.config.WirelessTerminalType; +import com.glodblock.github.loader.FCItems; +import com.mekeng.github.common.ItemAndBlocks; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; + +public class UniversalTerminalHelper { + private final static boolean isMekELoaded = Platform.isModLoaded("mekeng"); + public static final List wirelessTerminals = new ArrayList<>(); + public static final List terminals = new ArrayList<>(); + public static final List WIRELESS_TERMINAL_TYPE_LIST = Arrays.asList(WirelessTerminalType.values()); + + private static final boolean isMekEngLoaded = Platform.isModLoaded("mekeng"); + private static final boolean isAE2FCLoaded = Platform.isModLoaded("ae2fc"); + + static { + wirelessTerminals.add(AEApi.instance().definitions().items().wirelessTerminal().maybeStack(1).orElse(null)); + wirelessTerminals.add(AEApi.instance().definitions().items().wirelessFluidTerminal().maybeStack(1).orElse(null)); + wirelessTerminals.add(AEApi.instance().definitions().items().wirelessCraftingTerminal().maybeStack(1).orElse(null)); + wirelessTerminals.add(AEApi.instance().definitions().items().wirelessPatternTerminal().maybeStack(1).orElse(null)); + + terminals.add(AEApi.instance().definitions().parts().terminal().maybeStack(1).orElse(null)); + terminals.add(AEApi.instance().definitions().parts().craftingTerminal().maybeStack(1).orElse(null)); + terminals.add(AEApi.instance().definitions().parts().patternTerminal().maybeStack(1).orElse(null)); + terminals.add(AEApi.instance().definitions().parts().fluidTerminal().maybeStack(1).orElse(null)); + + if (isMekEngLoaded) { + wirelessTerminals.add(new ItemStack(ItemAndBlocks.WIRELESS_GAS_TERMINAL)); + terminals.add(new ItemStack(ItemAndBlocks.GAS_TERMINAL)); + } + + if (isAE2FCLoaded) { + wirelessTerminals.add(new ItemStack(FCItems.WIRELESS_FLUID_PATTERN_TERMINAL)); + terminals.add(new ItemStack(FCItems.PART_FLUID_PATTERN_TERMINAL)); + } + } + + public static boolean isWirelessTerminal(ItemStack stack) { + if (stack == ItemStack.EMPTY) return false; + + int itemDamage = stack.getItemDamage(); + Item item = stack.getItem(); + + ItemStack wirelessTerminal = AEApi.instance().definitions().items().wirelessTerminal().maybeStack(1).orElse(null); + if (wirelessTerminal != null && wirelessTerminal.getItem() == item && wirelessTerminal.getItemDamage() == itemDamage) + return true; + + ItemStack wirelessFluidTerminal = AEApi.instance().definitions().items().wirelessFluidTerminal().maybeStack(1).orElse(null); + if (wirelessFluidTerminal != null && wirelessFluidTerminal.getItem() == item && wirelessFluidTerminal.getItemDamage() == itemDamage) + return true; + + if (isMekEngLoaded) { + ItemStack wirelessGasTerminal = new ItemStack(ItemAndBlocks.WIRELESS_GAS_TERMINAL); + if (wirelessGasTerminal.getItem() == item && wirelessGasTerminal.getItemDamage() == itemDamage) return true; + } + + if (isAE2FCLoaded) { + ItemStack fluidPatternWirelessTerminal = new ItemStack(FCItems.WIRELESS_FLUID_PATTERN_TERMINAL); + if (fluidPatternWirelessTerminal.getItem() == item && fluidPatternWirelessTerminal.getItemDamage() == itemDamage) return true; + } + + ItemStack wirelessCraftingTerminal = AEApi.instance().definitions().items().wirelessCraftingTerminal().maybeStack(1).orElse(null); + if (wirelessCraftingTerminal != null && wirelessCraftingTerminal.getItem() == item && wirelessCraftingTerminal.getItemDamage() == itemDamage) + return true; + + ItemStack wirelessPatternTerminal = AEApi.instance().definitions().items().wirelessPatternTerminal().maybeStack(1).orElse(null); + if (wirelessPatternTerminal != null && wirelessPatternTerminal.getItem() == item && wirelessPatternTerminal.getItemDamage() == itemDamage) + return true; + + return false; + } + + public static boolean isTerminal(ItemStack stack) { + if (stack == ItemStack.EMPTY) return false; + + Item item = stack.getItem(); + int itemDamage = stack.getItemDamage(); + + ItemStack terminal = AEApi.instance().definitions().parts().terminal().maybeStack(1).orElse(null); + if (terminal != null && terminal.getItem() == item && terminal.getItemDamage() == itemDamage) return true; + + ItemStack fluidTerminal = AEApi.instance().definitions().parts().fluidTerminal().maybeStack(1).orElse(null); + if (fluidTerminal != null && fluidTerminal.getItem() == item && fluidTerminal.getItemDamage() == itemDamage) + return true; + + if (isMekEngLoaded) { + ItemStack gasTerminal = new ItemStack(ItemAndBlocks.GAS_TERMINAL); + if (gasTerminal.getItem() == item && gasTerminal.getItemDamage() == itemDamage) return true; + } + + if (isAE2FCLoaded) { + ItemStack fluidPatternTerminal = new ItemStack(FCItems.PART_FLUID_PATTERN_TERMINAL); + if (fluidPatternTerminal.getItem() == item && fluidPatternTerminal.getItemDamage() == itemDamage) return true; + } + + ItemStack craftingTerminal = AEApi.instance().definitions().parts().craftingTerminal().maybeStack(1).orElse(null); + if (craftingTerminal != null && craftingTerminal.getItem() == item && craftingTerminal.getItemDamage() == itemDamage) + return true; + + ItemStack patternTerminal = AEApi.instance().definitions().parts().patternTerminal().maybeStack(1).orElse(null); + if (patternTerminal != null && patternTerminal.getItem() == item && patternTerminal.getItemDamage() == itemDamage) + return true; + + ItemStack interfaceTerminal = AEApi.instance().definitions().parts().interfaceTerminal().maybeStack(1).orElse(null); + if (interfaceTerminal != null && interfaceTerminal.getItem() == item && interfaceTerminal.getItemDamage() == itemDamage) + return true; + + return false; + } + + public static WirelessTerminalType getTerminalType(ItemStack stack) { + if (stack == ItemStack.EMPTY) return null; + + Item item = stack.getItem(); + int itemDamage = stack.getItemDamage(); + + ItemStack terminal = AEApi.instance().definitions().parts().terminal().maybeStack(1).orElse(null); + if (terminal != null && terminal.getItem() == item && terminal.getItemDamage() == itemDamage) { + return WirelessTerminalType.ITEM; + } + + ItemStack fluidTerminal = AEApi.instance().definitions().parts().fluidTerminal().maybeStack(1).orElse(null); + if (fluidTerminal != null && fluidTerminal.getItem() == item && fluidTerminal.getItemDamage() == itemDamage) { + return WirelessTerminalType.FLUID; + } + + ItemStack craftingTerminal = AEApi.instance().definitions().parts().craftingTerminal().maybeStack(1).orElse(null); + if (craftingTerminal != null && fluidTerminal.getItem() == item && craftingTerminal.getItemDamage() == itemDamage) { + return WirelessTerminalType.CRAFTING; + } + + ItemStack patternTerminal = AEApi.instance().definitions().parts().patternTerminal().maybeStack(1).orElse(null); + if (patternTerminal != null && patternTerminal.getItem() == item && patternTerminal.getItemDamage() == itemDamage) { + return WirelessTerminalType.PATTERN; + } + + ItemStack interfaceTerminal = AEApi.instance().definitions().parts().interfaceTerminal().maybeStack(1).orElse(null); + if (interfaceTerminal != null && interfaceTerminal.getItem() == item && interfaceTerminal.getItemDamage() == itemDamage) { + return WirelessTerminalType.INTERFACE; + } + + //Wireless Terminal + + ItemStack wirelessTerminal = AEApi.instance().definitions().items().wirelessTerminal().maybeStack(1).orElse(null); + if (wirelessTerminal != null && wirelessTerminal.getItem() == item && wirelessTerminal.getItemDamage() == itemDamage) { + return WirelessTerminalType.ITEM; + } + + ItemStack wirelessFluidTerminal = AEApi.instance().definitions().items().wirelessFluidTerminal().maybeStack(1).orElse(null); + if (wirelessFluidTerminal != null && wirelessFluidTerminal.getItem() == item && wirelessFluidTerminal.getItemDamage() == itemDamage) { + return WirelessTerminalType.FLUID; + } + + ItemStack wirelessCraftingTerminal = AEApi.instance().definitions().items().wirelessCraftingTerminal().maybeStack(1).orElse(null); + if (wirelessCraftingTerminal != null && wirelessCraftingTerminal.getItem() == item && wirelessCraftingTerminal.getItemDamage() == itemDamage) { + return WirelessTerminalType.CRAFTING; + } + + ItemStack wirelessPatternTerminal = AEApi.instance().definitions().items().wirelessPatternTerminal().maybeStack(1).orElse(null); + if (wirelessPatternTerminal != null && wirelessPatternTerminal.getItem() == item && wirelessPatternTerminal.getItemDamage() == itemDamage) { + return WirelessTerminalType.PATTERN; + } + + ItemStack wirelessInterfaceTerminal = AEApi.instance().definitions().items().wirelessInterfaceTerminal().maybeStack(1).orElse(null); + if (wirelessInterfaceTerminal != null && wirelessInterfaceTerminal.getItem() == item && wirelessInterfaceTerminal.getItemDamage() == itemDamage) { + return WirelessTerminalType.INTERFACE; + } + + //MekEng Integration + if (isMekEngLoaded) { + ItemStack gasTerminal = new ItemStack(ItemAndBlocks.GAS_TERMINAL); + if (gasTerminal.getItem() == item && gasTerminal.getItemDamage() == itemDamage) { + return WirelessTerminalType.GAS; + } + + ItemStack wirelessGasTerminal = new ItemStack(ItemAndBlocks.WIRELESS_GAS_TERMINAL); + if (wirelessGasTerminal.getItem() == item && wirelessGasTerminal.getItemDamage() == itemDamage) { + return WirelessTerminalType.GAS; + } + } + + if (isAE2FCLoaded) { + ItemStack fluidPatternTerminal = new ItemStack(FCItems.PART_FLUID_PATTERN_TERMINAL); + if (fluidPatternTerminal.getItem() == item && fluidPatternTerminal.getItemDamage() == itemDamage) { + return WirelessTerminalType.FLUID_PATTERN; + } + + ItemStack fluidPatternWirelessTerminal = new ItemStack(FCItems.WIRELESS_FLUID_PATTERN_TERMINAL); + if (fluidPatternWirelessTerminal.getItem() == item && fluidPatternWirelessTerminal.getItemDamage() == itemDamage) { + return WirelessTerminalType.FLUID_PATTERN; + } + } + + return null; + } + + public static boolean isModuleValid(WirelessTerminalType type) { + return switch (type) { + case FLUID_PATTERN -> Platform.isModLoaded("ae2fc"); + case GAS -> Platform.isModLoaded("mekeng"); + default -> true; + }; + } + + + public static ItemStack changeMode(ItemStack itemStack, EntityPlayer player, NBTTagCompound tag) { + EnumSet installedModules = getInstalledModules(itemStack); + int type = tag.getInteger("type"); + WirelessTerminalType terminalType; + do { + type = (type + 1) % WIRELESS_TERMINAL_TYPE_LIST.size(); + terminalType = WIRELESS_TERMINAL_TYPE_LIST.get(type); + + } while (!isModuleValid(terminalType) || !installedModules.contains(terminalType)); + + tag.setInteger("type", type); + + return itemStack; + } + + public static EnumSet getInstalledModules(ItemStack itemStack) { + if (itemStack == ItemStack.EMPTY || itemStack.getItem() == ItemStack.EMPTY.getItem()) { + return EnumSet.noneOf(WirelessTerminalType.class); + } + + NBTTagCompound tag = Platform.openNbtData(itemStack); + int installed = tag.hasKey("modules") ? tag.getInteger("modules") : 0; + + EnumSet set = EnumSet.noneOf(WirelessTerminalType.class); + + for (WirelessTerminalType x : WirelessTerminalType.values()) { + if ((installed >> x.ordinal()) % 2 == 1) { + set.add(x); + } + } + + return set; + } + + public static boolean isInstalled(ItemStack itemStack, WirelessTerminalType module) { + if (itemStack == ItemStack.EMPTY || itemStack.getItem() == ItemStack.EMPTY.getItem()) { + return false; + } + + NBTTagCompound tag = Platform.openNbtData(itemStack); + int installed = tag.hasKey("modules") ? tag.getInteger("modules") : 0; + + return 1 == (installed >>> module.ordinal()) % 2; + } + + public static void installModule(ItemStack itemStack, WirelessTerminalType module) { + if (isInstalled(itemStack, module) || itemStack == ItemStack.EMPTY) { + return; + } + + int install = 1 << module.ordinal(); + + NBTTagCompound tag = Platform.openNbtData(itemStack); + + int installed; + if (tag.hasKey("modules")) { + installed = tag.getInteger("modules") + install; + } else { + installed = install; + } + + tag.setInteger("modules", installed); + } +} diff --git a/src/main/java/co/neeve/nae2/common/integration/jei/NAEJEIPlugin.java b/src/main/java/co/neeve/nae2/common/integration/jei/NAEJEIPlugin.java index 6bbeb09..6596384 100644 --- a/src/main/java/co/neeve/nae2/common/integration/jei/NAEJEIPlugin.java +++ b/src/main/java/co/neeve/nae2/common/integration/jei/NAEJEIPlugin.java @@ -2,6 +2,7 @@ import appeng.api.definitions.IItemDefinition; import appeng.api.implementations.items.IStorageCell; +import co.neeve.nae2.common.features.Features; import co.neeve.nae2.common.features.subfeatures.JEIFeatures; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; @@ -16,6 +17,7 @@ import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -108,5 +110,13 @@ public void register(@NotNull IModRegistry registry) { for (var blacklistEntry : ingredientBlacklist) { blacklistEntry.maybeStack(1).ifPresent(blacklist::addIngredientToBlacklist); } + + if (Features.UNIVERSAL_TERMINAL.isEnabled()) { + List recipeWrappers = new ArrayList<>(); + recipeWrappers.add(new UniversalTerminalRecipeWrapper(true)); + recipeWrappers.add(new UniversalTerminalRecipeWrapper(false)); + + registry.addRecipes(recipeWrappers,VanillaRecipeCategoryUid.CRAFTING); + } } } diff --git a/src/main/java/co/neeve/nae2/common/integration/jei/UniversalTerminalRecipeWrapper.java b/src/main/java/co/neeve/nae2/common/integration/jei/UniversalTerminalRecipeWrapper.java new file mode 100644 index 0000000..b5121ce --- /dev/null +++ b/src/main/java/co/neeve/nae2/common/integration/jei/UniversalTerminalRecipeWrapper.java @@ -0,0 +1,44 @@ +package co.neeve.nae2.common.integration.jei; + +import co.neeve.nae2.NAE2; +import co.neeve.nae2.common.helpers.UniversalTerminalHelper; +import mezz.jei.api.ingredients.IIngredients; +import mezz.jei.api.ingredients.VanillaTypes; +import mezz.jei.api.recipe.IRecipeWrapper; +import net.minecraft.item.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +public class UniversalTerminalRecipeWrapper implements IRecipeWrapper { + public UniversalTerminalRecipeWrapper(boolean isUniversalTerminal) { + this.isUniversalTerminal = isUniversalTerminal; + } + + private final boolean isUniversalTerminal; + + + @Override + public void getIngredients(IIngredients iIngredients) { + List> inputList = new ArrayList<>(); + + if (isUniversalTerminal) { + List input = new ArrayList<>(); + ItemStack itemStack = NAE2.definitions().items().universalWirelessTerminal().maybeStack(1).orElse(null); + if (itemStack != ItemStack.EMPTY) { + input.add(itemStack); + } + + inputList.add(input); + } else { + inputList.add(UniversalTerminalHelper.wirelessTerminals); + } + + inputList.add(UniversalTerminalHelper.terminals); + + iIngredients.setInputLists(VanillaTypes.ITEM, inputList); + if (NAE2.definitions().items().universalWirelessTerminal().maybeStack(1).isPresent()){ + iIngredients.setOutput(VanillaTypes.ITEM,NAE2.definitions().items().universalWirelessTerminal().maybeStack(1).get()); + } + } +} diff --git a/src/main/java/co/neeve/nae2/common/items/WirelessTerminalUniversal.java b/src/main/java/co/neeve/nae2/common/items/WirelessTerminalUniversal.java new file mode 100644 index 0000000..5b397b4 --- /dev/null +++ b/src/main/java/co/neeve/nae2/common/items/WirelessTerminalUniversal.java @@ -0,0 +1,148 @@ +package co.neeve.nae2.common.items; + +import appeng.api.AEApi; +import appeng.api.config.Actionable; +import appeng.core.sync.GuiBridge; +import appeng.core.sync.GuiWrapper; +import appeng.items.tools.powered.ToolWirelessTerminal; +import appeng.util.Platform; +import co.neeve.nae2.NAE2; +import co.neeve.nae2.common.api.config.WirelessTerminalType; +import co.neeve.nae2.common.helpers.UniversalTerminalHelper; +import com.glodblock.github.inventory.GuiType; +import com.glodblock.github.util.Util; +import com.mekeng.github.common.container.handler.AEGuiBridge; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.text.translation.I18n; +import net.minecraft.world.World; +import net.minecraftforge.fml.common.network.IGuiHandler; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + + +import java.util.List; + +import static co.neeve.nae2.common.helpers.UniversalTerminalHelper.*; + +public class WirelessTerminalUniversal extends ToolWirelessTerminal { + @Override + public IGuiHandler getGuiHandler(ItemStack is) { + return switch (WIRELESS_TERMINAL_TYPE_LIST.get(Platform.openNbtData(is).getInteger("type"))) { + case ITEM -> GuiBridge.GUI_WIRELESS_TERM; + case FLUID -> GuiBridge.GUI_WIRELESS_FLUID_TERMINAL; + case GAS -> GuiWrapper.INSTANCE.wrap(AEGuiBridge.WIRELESS_GAS_TERM); + case CRAFTING -> GuiBridge.GUI_WIRELESS_CRAFTING_TERMINAL; + case PATTERN -> GuiBridge.GUI_WIRELESS_PATTERN_TERMINAL; + case INTERFACE -> GuiBridge.GUI_WIRELESS_INTERFACE_TERMINAL; + default -> GuiBridge.GUI_WIRELESS_TERM; + }; + } + + @Override + public boolean canHandle(ItemStack is) { + return is.getItem() == NAE2.definitions().items().universalWirelessTerminal().maybeItem().orElse(null); + } + + @Override + public ActionResult onItemRightClick(World w, EntityPlayer player, EnumHand hand) { + ItemStack stack = player.getHeldItem(hand); + NBTTagCompound tagCompound = Platform.openNbtData(stack); + if (w.isRemote) { + if (player.isSneaking()) { + return new ActionResult(EnumActionResult.SUCCESS, stack); + } + if (!tagCompound.hasKey("type")) { + tagCompound.setInteger("type", 0); + } + return new ActionResult(EnumActionResult.SUCCESS, stack); + } + + if (!tagCompound.hasKey("type")) { + tagCompound.setInteger("type", 0); + } + if (player.isSneaking()) { + if (stack == ItemStack.EMPTY) { + return new ActionResult(EnumActionResult.FAIL, stack); + } + return new ActionResult(EnumActionResult.SUCCESS, changeMode(stack, player, tagCompound)); + } + + switch (WIRELESS_TERMINAL_TYPE_LIST.get(Platform.openNbtData(stack).getInteger("type"))) { + case FLUID_PATTERN -> { + if (UniversalTerminalHelper.isModuleValid(WirelessTerminalType.FLUID_PATTERN)) { + Util.openWirelessTerminal(player.getHeldItem(hand), hand == EnumHand.MAIN_HAND ? player.inventory.currentItem : 40, false, w, player, GuiType.WIRELESS_FLUID_PATTERN_TERMINAL); + } + } + default -> AEApi.instance().registries().wireless().openWirelessTerminalGui(stack, w, player); + } + + return new ActionResult(EnumActionResult.SUCCESS, stack); + } + + @Override + @SideOnly(Side.CLIENT) + public void addCheckedInformation(ItemStack stack, World world, List lines, ITooltipFlag advancedTooltips) { + NBTTagCompound tag = Platform.openNbtData(stack); + if (!tag.hasKey("type")) { + tag.setInteger("type", 0); + } + + lines.add( + I18n.translateToLocal("nae2.tooltip.universal_wireless_terminal.mode") + ": " + I18n.translateToLocal( + "nae2.tooltip.universal_wireless_terminal." + WirelessTerminalType.values()[tag.getInteger( + "type" + )].toString().toLowerCase() + ) + ); + + lines.add(I18n.translateToLocal("nae2.tooltip.universal_wireless_terminal.installed")); + for (WirelessTerminalType wirelessTerminalType : getInstalledModules(stack)) { + lines.add("- " + I18n.translateToLocal("nae2.tooltip.universal_wireless_terminal." + wirelessTerminalType.name().toLowerCase())); + } + + super.addCheckedInformation(stack, world, lines, advancedTooltips); + } + + @Override + protected void getCheckedSubItems(CreativeTabs creativeTab, NonNullList itemStacks) { + if (!isInCreativeTab(creativeTab)) { + return; + } + int modulesValue = 0; + for (WirelessTerminalType type : WirelessTerminalType.values()) { + if (UniversalTerminalHelper.isModuleValid(type)) { + modulesValue |= (1 << type.ordinal()); + } + } + + NBTTagCompound tag = new NBTTagCompound(); + tag.setInteger("modules", modulesValue); + ItemStack itemStack = new ItemStack(this); + itemStack.setTagCompound(tag); + itemStacks.add(itemStack.copy()); + injectAEPower(itemStack, getAEMaxPower(itemStack), Actionable.MODULATE); + itemStacks.add(itemStack); + } + + @Override + public String getHighlightTip(ItemStack item, String displayName) { + NBTTagCompound tag = Platform.openNbtData(item); + if (!tag.hasKey("type")) { + tag.setInteger("type", 0); + } + + return displayName + " - " + I18n.translateToLocal( + "nae2.tooltip.universal_wireless_terminal." + WirelessTerminalType.values()[tag.getInteger( + "type" + )].toString().toLowerCase() + ); + } +} diff --git a/src/main/java/co/neeve/nae2/common/net/messages/PatternMultiToolPacket.java b/src/main/java/co/neeve/nae2/common/net/messages/PatternMultiToolPacket.java index c33db68..f321208 100644 --- a/src/main/java/co/neeve/nae2/common/net/messages/PatternMultiToolPacket.java +++ b/src/main/java/co/neeve/nae2/common/net/messages/PatternMultiToolPacket.java @@ -16,6 +16,8 @@ import co.neeve.nae2.common.net.INAEMessage; import com.glodblock.github.common.item.ItemFluidDrop; import com.glodblock.github.common.item.ItemFluidEncodedPattern; +import com.glodblock.github.common.item.fake.FakeFluids; +import com.glodblock.github.common.item.fake.FakeItemRegister; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.InventoryCrafting; @@ -23,6 +25,7 @@ import net.minecraft.item.crafting.CraftingManager; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; @@ -177,9 +180,9 @@ private void searchAndReplace(IContainerPatternMultiTool host, EntityPlayerMP pl list.set(idx, data); } else if (fluidReplacement && stack.getItem() instanceof ItemFluidDrop) { // ¯\_(ツ)_/¯ - var fluidStack = ItemFluidDrop.getFluidStack(stack); - if (fluidStackIn.isFluidEqual(fluidStack)) { - var ifd = ItemFluidDrop.newStack(fluidStackOut); + var fluidStack = FakeItemRegister.getStack(stack); + if (fluidStackIn.isFluidEqual(((FluidStack) fluidStack))) { + var ifd = FakeFluids.packFluid2Drops(fluidStackOut); NBTTagCompound ifdCompound; if (ifd == null || (ifdCompound = ifd.getTagCompound()) == null) continue; diff --git a/src/main/java/co/neeve/nae2/common/recipes/UniversalTerminalRecipe.java b/src/main/java/co/neeve/nae2/common/recipes/UniversalTerminalRecipe.java new file mode 100644 index 0000000..1bff9df --- /dev/null +++ b/src/main/java/co/neeve/nae2/common/recipes/UniversalTerminalRecipe.java @@ -0,0 +1,169 @@ +package co.neeve.nae2.common.recipes; + +import appeng.api.config.Actionable; +import appeng.api.features.INetworkEncodable; +import appeng.api.implementations.items.IAEItemPowerStorage; +import appeng.util.Platform; +import co.neeve.nae2.NAE2; +import co.neeve.nae2.common.api.config.WirelessTerminalType; +import co.neeve.nae2.common.helpers.UniversalTerminalHelper; +import co.neeve.nae2.common.items.WirelessTerminalUniversal; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.NonNullList; +import net.minecraft.world.World; +import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.registries.IForgeRegistryEntry; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +public class UniversalTerminalRecipe extends IForgeRegistryEntry.Impl implements IRecipe { + + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { + boolean hasWireless = false; + boolean isUniversal = false; + boolean hasTerminal = false; + EnumSet terminals = EnumSet.noneOf(WirelessTerminalType.class); + ItemStack terminal = ItemStack.EMPTY; + int size = inv.getSizeInventory(); + for (int i = 0; i < size; i++) { + ItemStack stack = inv.getStackInSlot(i); + if (!stack.isEmpty()) { + Item item = stack.getItem(); + if (item == NAE2.definitions().items().universalWirelessTerminal().maybeItem().orElse(null)) { + hasWireless = true; + isUniversal = true; + terminal = stack; + } + + if (UniversalTerminalHelper.isWirelessTerminal(stack)) { + if (hasWireless) { + return false; + } + hasWireless = true; + terminal = stack; + } else if (UniversalTerminalHelper.isTerminal(stack)) { + hasTerminal = true; + + WirelessTerminalType terminalType = UniversalTerminalHelper.getTerminalType(stack); + + if (terminals.contains(terminalType)) { + return false; + } + + if (terminalType != null) { + terminals.add(terminalType); + } + } + } + } + + if (!(hasTerminal && hasWireless)) { + return false; + } + + if (isUniversal) { + for (WirelessTerminalType terminalType : terminals) { + if (UniversalTerminalHelper.isInstalled(terminal, terminalType)) { + return false; + } + } + + return true; + } + + WirelessTerminalType terminalType = UniversalTerminalHelper.getTerminalType(terminal); + + for (WirelessTerminalType wirelessTerminalType : terminals) { + if (wirelessTerminalType == terminalType) { + return false; + } + } + + return true; + + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting inv) { + boolean isUniversal = false; + EnumSet terminals = EnumSet.noneOf(WirelessTerminalType.class); + ItemStack terminal = ItemStack.EMPTY; + for (int i = 0; i < inv.getSizeInventory(); i++) { + ItemStack stack = inv.getStackInSlot(i); + if (!stack.isEmpty()) { + Item item = stack.getItem(); + Item universalTerminalItem = NAE2.definitions().items().universalWirelessTerminal().maybeItem().orElse(null); + if (item == universalTerminalItem) { + isUniversal = true; + terminal = stack.copy(); + } else if (UniversalTerminalHelper.isWirelessTerminal(stack)) { + terminal = stack.copy(); + } else if (UniversalTerminalHelper.isTerminal(stack)) { + WirelessTerminalType terminalType = UniversalTerminalHelper.getTerminalType(stack); + if (terminalType != null) { + terminals.add(terminalType); + } + } + } + } + + if (isUniversal) { + for (WirelessTerminalType terminalType : terminals) { + UniversalTerminalHelper.installModule(terminal, terminalType); + } + } else { + WirelessTerminalType terminalType = UniversalTerminalHelper.getTerminalType(terminal); + ItemStack universalTerminal = NAE2.definitions().items().universalWirelessTerminal().maybeStack(1).orElse(ItemStack.EMPTY); + + universalTerminal.setTagCompound(terminal.getTagCompound()); + + if (terminalType != null) { + UniversalTerminalHelper.installModule(universalTerminal, terminalType); + Platform.openNbtData(universalTerminal).setInteger("type", terminalType.ordinal()); + } + + if (terminalType == WirelessTerminalType.PATTERN) { + NBTTagCompound compound = Platform.openNbtData(universalTerminal); + compound.setTag("craftingGridPattern",compound.getTag("craftingGrid")); + compound.removeTag("craftingGrid"); + } + + terminal = universalTerminal; + for (WirelessTerminalType x : terminals) { + UniversalTerminalHelper.installModule(terminal, x); + } + } + + return terminal; + } + + @Override + public boolean canFit(int width, int height) { + return (width >= 1 && height >= 2) || (width >= 2 && height >= 1); + } + + @Override + public ItemStack getRecipeOutput() { + if (NAE2.definitions().items().universalWirelessTerminal().maybeStack(1).isPresent()) { + ItemStack itemStack = NAE2.definitions().items().universalWirelessTerminal().maybeStack(1).get(); + itemStack.setItemDamage(1); + + return itemStack; + } + + return ItemStack.EMPTY; + } + + @Override + public NonNullList getRemainingItems(InventoryCrafting inv) { + return ForgeHooks.defaultRecipeGetRemainingItems(inv); + } +} diff --git a/src/main/java/co/neeve/nae2/common/registration/Registration.java b/src/main/java/co/neeve/nae2/common/registration/Registration.java index 0794048..3fd68ef 100644 --- a/src/main/java/co/neeve/nae2/common/registration/Registration.java +++ b/src/main/java/co/neeve/nae2/common/registration/Registration.java @@ -5,7 +5,9 @@ import appeng.core.AEConfig; import appeng.core.features.AEFeature; import appeng.util.Platform; +import co.neeve.nae2.common.features.Features; import co.neeve.nae2.common.integration.ae2fc.AE2FC; +import co.neeve.nae2.common.recipes.UniversalTerminalRecipe; import co.neeve.nae2.common.recipes.handlers.DisassembleRecipe; import co.neeve.nae2.common.registration.definitions.*; import co.neeve.nae2.common.registration.registry.Registry; @@ -83,6 +85,10 @@ public void registerRecipes(RegistryEvent.Register event) { registry.register(new DisassembleRecipe().setRegistryName("disassemble")); } + if (Features.UNIVERSAL_TERMINAL.isEnabled()) { + registry.register(new UniversalTerminalRecipe().setRegistryName("universal_terminal")); + } + this.registry.getBootstrapComponents(IRecipeRegistrationComponent.class) .forEachRemaining(b -> b.recipeRegistration(side, registry)); } diff --git a/src/main/java/co/neeve/nae2/common/registration/definitions/Items.java b/src/main/java/co/neeve/nae2/common/registration/definitions/Items.java index 1b46900..2f17ef6 100644 --- a/src/main/java/co/neeve/nae2/common/registration/definitions/Items.java +++ b/src/main/java/co/neeve/nae2/common/registration/definitions/Items.java @@ -3,6 +3,8 @@ import appeng.api.AEApi; import appeng.api.config.Upgrades; import appeng.api.definitions.IItemDefinition; +import appeng.api.features.IWirelessTermHandler; +import appeng.bootstrap.components.IInitComponent; import appeng.bootstrap.components.IPostInitComponent; import appeng.bootstrap.components.IRecipeRegistrationComponent; import appeng.core.features.ItemDefinition; @@ -11,6 +13,7 @@ import co.neeve.nae2.common.features.Features; import co.neeve.nae2.common.features.subfeatures.VoidCellFeatures; import co.neeve.nae2.common.items.VirtualPattern; +import co.neeve.nae2.common.items.WirelessTerminalUniversal; import co.neeve.nae2.common.items.cells.DenseFluidCell; import co.neeve.nae2.common.items.cells.DenseGasCell; import co.neeve.nae2.common.items.cells.DenseItemCell; @@ -57,6 +60,7 @@ public class Items implements Definitions { private final IItemDefinition storageCellGas4096K; private final IItemDefinition storageCellGas16384K; private final IItemDefinition virtualPattern; + private final IItemDefinition universalWirelessTerminal; public Items(Registry registry) { this.virtualPattern = this.registerById(registry.item("virtual_pattern", VirtualPattern::new) @@ -168,8 +172,7 @@ public Items(Registry registry) { .features(Features.DENSE_FLUID_CELLS) .build()); - this.storageCellGas256K = this.registerById(registry.item("storage_cell_gas_256k", () -> - new DenseGasCell(Materials.MaterialType.CELL_GAS_PART_256K, + this.storageCellGas256K = this.registerById(registry.item("storage_cell_gas_256k", () -> new DenseGasCell(Materials.MaterialType.CELL_GAS_PART_256K, (int) Math.pow(2, 8))) .features(Features.DENSE_GAS_CELLS) .build()); @@ -192,6 +195,14 @@ public Items(Registry registry) { .features(Features.DENSE_GAS_CELLS) .build()); + this.universalWirelessTerminal = this.registerById(registry.item("universal_wireless_terminal", WirelessTerminalUniversal::new) + .features(Features.UNIVERSAL_TERMINAL) + .bootstrap((item) -> (IInitComponent) r -> { + AEApi.instance().registries().wireless().registerWirelessHandler((IWirelessTermHandler) item); + Upgrades.MAGNET.registerItem(new ItemStack(item),1); + }) + .build()); + registry.addBootstrapComponent((IPostInitComponent) r -> { var items = AEApi.instance().definitions().items(); var cellDef = items.cell1k(); @@ -328,4 +339,6 @@ public IItemDefinition storageCellGas4096K() { public IItemDefinition storageCellGas16384K() { return this.storageCellGas16384K; } + + public IItemDefinition universalWirelessTerminal() {return this.universalWirelessTerminal;} } diff --git a/src/main/java/co/neeve/nae2/mixin/universalterminal/MixinContainerWirelessPatternTerminal.java b/src/main/java/co/neeve/nae2/mixin/universalterminal/MixinContainerWirelessPatternTerminal.java new file mode 100644 index 0000000..b5669d1 --- /dev/null +++ b/src/main/java/co/neeve/nae2/mixin/universalterminal/MixinContainerWirelessPatternTerminal.java @@ -0,0 +1,45 @@ +package co.neeve.nae2.mixin.universalterminal; + +import appeng.container.implementations.ContainerWirelessPatternTerminal; +import appeng.helpers.WirelessTerminalGuiObject; +import appeng.tile.inventory.AppEngInternalInventory; +import co.neeve.nae2.NAE2; +import net.minecraft.nbt.NBTTagCompound; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(value = ContainerWirelessPatternTerminal.class, remap = false) +public abstract class MixinContainerWirelessPatternTerminal { + + @Shadow + @Final + private WirelessTerminalGuiObject wirelessTerminalGUIObject; + + @Redirect( + method = "loadFromNBT", + at = @At(value = "INVOKE", target = "Lappeng/tile/inventory/AppEngInternalInventory;readFromNBT(Lnet/minecraft/nbt/NBTTagCompound;Ljava/lang/String;)V", ordinal = 0) + ) + private void loadFromNBT(AppEngInternalInventory instance, NBTTagCompound data, String name) { + if (NAE2.definitions().items().universalWirelessTerminal().isSameAs(wirelessTerminalGUIObject.getItemStack())) { + instance.readFromNBT(data, "craftingGridPattern"); + } else { + instance.readFromNBT(data, name); + } + } + + @Redirect( + method = "saveChanges", + at = @At(value = "INVOKE", target = "Lappeng/tile/inventory/AppEngInternalInventory;writeToNBT(Lnet/minecraft/nbt/NBTTagCompound;Ljava/lang/String;)V", ordinal = 0) + ) + public void saveChanges(AppEngInternalInventory instance, NBTTagCompound data, String name) { + if (NAE2.definitions().items().universalWirelessTerminal().isSameAs(wirelessTerminalGUIObject.getItemStack())) { + instance.writeToNBT(data, "craftingGridPattern"); + } else { + instance.writeToNBT(data, name); + } + + } +} diff --git a/src/main/resources/assets/nae2/lang/en_us.lang b/src/main/resources/assets/nae2/lang/en_us.lang index a1c83da..f265bfa 100644 --- a/src/main/resources/assets/nae2/lang/en_us.lang +++ b/src/main/resources/assets/nae2/lang/en_us.lang @@ -6,6 +6,7 @@ itemGroup.nae2=Neeve's AE2:EL Additions # Items item.nae2.invalid.name=Invalid or Disabled Item item.nae2.pattern_multiplier.name=Pattern Multi-Tool +item.nae2.universal_wireless_terminal.name=Universal Wireless Terminal # Cells item.nae2.storage_cell_void.name=ME Void Storage Cell @@ -108,3 +109,18 @@ nae2.jei.cellview.keybind=Press %s to view contents nae2.exposer.tooltip=Exposes the network contents as capabilities. The cooler ME Interface. nae2.exposer.noneregistered=No handlers registered. nae2.exposer.registered=Registered handlers: + +# Universal Wireless Terminal +nae2.tooltip.universal_wireless_terminal.mode=Mode +nae2.tooltip.universal_wireless_terminal.installed=Installed +nae2.tooltip.universal_wireless_terminal.item=Item +nae2.tooltip.universal_wireless_terminal.fluid=Fluid +nae2.tooltip.universal_wireless_terminal.gas=Gas +nae2.tooltip.universal_wireless_terminal.crafting=Crafting +nae2.tooltip.universal_wireless_terminal.pattern=Pattern +nae2.tooltip.universal_wireless_terminal.interface=Interface +nae2.tooltip.universal_wireless_terminal.fluid_pattern=Fluid Pattern + + + + diff --git a/src/main/resources/assets/nae2/lang/zh_cn.lang b/src/main/resources/assets/nae2/lang/zh_cn.lang index 3dc412a..9f1f673 100644 --- a/src/main/resources/assets/nae2/lang/zh_cn.lang +++ b/src/main/resources/assets/nae2/lang/zh_cn.lang @@ -6,6 +6,7 @@ itemGroup.nae2=Neeve的AE2:EL附加工具 # Items item.nae2.invalid.name=无效或禁用的物品 item.nae2.pattern_multiplier.name=多功能样板工具 +item.nae2.universal_wireless_terminal.name=通用无线终端 # Cells item.nae2.storage_cell_void.name=ME虚空存储元件 @@ -90,3 +91,15 @@ nae2.jei.cellview.hover.1=已占用 %s 种类型。 nae2.jei.cellview.hover.2=每种占用类型均会损耗容量。 nae2.jei.cellview.hover.3=%s 字节/类型 * %s = %s 字节损耗。 nae2.jei.cellview.keybind=按下 %s 来浏览内容 + +# Universal Wireless Terminal +nae2.tooltip.universal_wireless_terminal.mode=模式 +nae2.tooltip.universal_wireless_terminal.installed=已安装 +nae2.tooltip.universal_wireless_terminal.item=物品 +nae2.tooltip.universal_wireless_terminal.fluid=流体 +nae2.tooltip.universal_wireless_terminal.gas=气体 +nae2.tooltip.universal_wireless_terminal.crafting=合成 +nae2.tooltip.universal_wireless_terminal.pattern=样板 +nae2.tooltip.universal_wireless_terminal.interface=接口 +nae2.tooltip.universal_wireless_terminal.fluid_pattern=流体样板 + diff --git a/src/main/resources/assets/nae2/models/item/universal_wireless_terminal.json b/src/main/resources/assets/nae2/models/item/universal_wireless_terminal.json new file mode 100644 index 0000000..d86af72 --- /dev/null +++ b/src/main/resources/assets/nae2/models/item/universal_wireless_terminal.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "nae2:item/universal_wireless_terminal" + } +} diff --git a/src/main/resources/assets/nae2/textures/item/universal_wireless_terminal.png b/src/main/resources/assets/nae2/textures/item/universal_wireless_terminal.png new file mode 100644 index 0000000..fd514aa Binary files /dev/null and b/src/main/resources/assets/nae2/textures/item/universal_wireless_terminal.png differ diff --git a/src/main/resources/mixins.nae2.universalterminal.json b/src/main/resources/mixins.nae2.universalterminal.json new file mode 100644 index 0000000..747c5c5 --- /dev/null +++ b/src/main/resources/mixins.nae2.universalterminal.json @@ -0,0 +1,11 @@ +{ + "package": "co.neeve.nae2.mixin", + "required": true, + "refmap": "mixins.nae2.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "universalterminal.MixinContainerWirelessPatternTerminal" + ] +} \ No newline at end of file