增加jei中shift左键拉取物品功能
This commit is contained in:
parent
c325cc1d39
commit
d4f57c85a3
|
|
@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1G
|
||||||
loom.platform = forge
|
loom.platform = forge
|
||||||
|
|
||||||
# Mod properties
|
# Mod properties
|
||||||
mod_version = 1.2.1-fix
|
mod_version = 1.2.2
|
||||||
maven_group = com.extendedae_plus
|
maven_group = com.extendedae_plus
|
||||||
archives_name = extendedae_plus
|
archives_name = extendedae_plus
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,12 @@ import com.extendedae_plus.ExtendedAEPlus;
|
||||||
import com.extendedae_plus.integration.jei.JeiRuntimeProxy;
|
import com.extendedae_plus.integration.jei.JeiRuntimeProxy;
|
||||||
import com.extendedae_plus.network.ModNetwork;
|
import com.extendedae_plus.network.ModNetwork;
|
||||||
import com.extendedae_plus.network.OpenCraftFromJeiC2SPacket;
|
import com.extendedae_plus.network.OpenCraftFromJeiC2SPacket;
|
||||||
|
import com.extendedae_plus.network.PullFromJeiOrCraftC2SPacket;
|
||||||
|
|
||||||
import appeng.api.stacks.GenericStack;
|
import appeng.api.stacks.GenericStack;
|
||||||
import appeng.integration.modules.jei.GenericEntryStackHelper;
|
import appeng.integration.modules.jei.GenericEntryStackHelper;
|
||||||
import mezz.jei.api.ingredients.ITypedIngredient;
|
import mezz.jei.api.ingredients.ITypedIngredient;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.client.event.ScreenEvent;
|
import net.minecraftforge.client.event.ScreenEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
|
@ -23,26 +25,47 @@ public final class InputEvents {
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onMouseButtonPre(ScreenEvent.MouseButtonPressed.Pre event) {
|
public static void onMouseButtonPre(ScreenEvent.MouseButtonPressed.Pre event) {
|
||||||
// 只处理中键按下
|
// 优先处理:Shift + 左键(拉取或下单)
|
||||||
if (event.getButton() != GLFW.GLFW_MOUSE_BUTTON_MIDDLE) return;
|
if (event.getButton() == GLFW.GLFW_MOUSE_BUTTON_LEFT && Screen.hasShiftDown()) {
|
||||||
|
double mouseX = event.getMouseX();
|
||||||
// 优先在 JEI 配方界面基于坐标获取;若无,再从覆盖层/书签获取
|
double mouseY = event.getMouseY();
|
||||||
double mouseX = event.getMouseX();
|
Optional<ITypedIngredient<?>> hovered = JeiRuntimeProxy.getIngredientUnderMouse(mouseX, mouseY);
|
||||||
double mouseY = event.getMouseY();
|
if (hovered.isEmpty()) {
|
||||||
Optional<ITypedIngredient<?>> hovered = JeiRuntimeProxy.getIngredientUnderMouse(mouseX, mouseY);
|
hovered = JeiRuntimeProxy.getIngredientUnderMouse();
|
||||||
if (hovered.isEmpty()) {
|
}
|
||||||
hovered = JeiRuntimeProxy.getIngredientUnderMouse();
|
if (hovered.isPresent()) {
|
||||||
|
ITypedIngredient<?> typed = hovered.get();
|
||||||
|
GenericStack stack = GenericEntryStackHelper.ingredientToStack(typed);
|
||||||
|
if (stack != null) {
|
||||||
|
// 发送到服务端:若网络有库存则拉取一组到空槽,否则若可合成则打开下单界面
|
||||||
|
ModNetwork.CHANNEL.sendToServer(new PullFromJeiOrCraftC2SPacket(stack));
|
||||||
|
// 消费此次点击,避免 JEI/原版对左键的其它处理
|
||||||
|
event.setCanceled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (hovered.isEmpty()) return;
|
|
||||||
|
|
||||||
ITypedIngredient<?> typed = hovered.get();
|
// 中键:打开 AE 下单界面(保持原有功能)
|
||||||
GenericStack stack = GenericEntryStackHelper.ingredientToStack(typed);
|
if (event.getButton() == GLFW.GLFW_MOUSE_BUTTON_MIDDLE) {
|
||||||
if (stack == null) return;
|
// 优先在 JEI 配方界面基于坐标获取;若无,再从覆盖层/书签获取
|
||||||
|
double mouseX = event.getMouseX();
|
||||||
|
double mouseY = event.getMouseY();
|
||||||
|
Optional<ITypedIngredient<?>> hovered = JeiRuntimeProxy.getIngredientUnderMouse(mouseX, mouseY);
|
||||||
|
if (hovered.isEmpty()) {
|
||||||
|
hovered = JeiRuntimeProxy.getIngredientUnderMouse();
|
||||||
|
}
|
||||||
|
if (hovered.isEmpty()) return;
|
||||||
|
|
||||||
// 发送到服务端,让其验证并打开 CraftAmountMenu
|
ITypedIngredient<?> typed = hovered.get();
|
||||||
ModNetwork.CHANNEL.sendToServer(new OpenCraftFromJeiC2SPacket(stack));
|
GenericStack stack = GenericEntryStackHelper.ingredientToStack(typed);
|
||||||
|
if (stack == null) return;
|
||||||
|
|
||||||
// 消费此次点击,避免 JEI/原版对中键的其它处理
|
// 发送到服务端,让其验证并打开 CraftAmountMenu
|
||||||
event.setCanceled(true);
|
ModNetwork.CHANNEL.sendToServer(new OpenCraftFromJeiC2SPacket(stack));
|
||||||
|
|
||||||
|
// 消费此次点击,避免 JEI/原版对中键的其它处理
|
||||||
|
event.setCanceled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import net.minecraftforge.network.simple.SimpleChannel;
|
||||||
import net.minecraftforge.network.NetworkDirection;
|
import net.minecraftforge.network.NetworkDirection;
|
||||||
|
|
||||||
import com.extendedae_plus.ExtendedAEPlus;
|
import com.extendedae_plus.ExtendedAEPlus;
|
||||||
|
import com.extendedae_plus.network.PullFromJeiOrCraftC2SPacket;
|
||||||
|
|
||||||
public class ModNetwork {
|
public class ModNetwork {
|
||||||
private static final String PROTOCOL_VERSION = "1";
|
private static final String PROTOCOL_VERSION = "1";
|
||||||
|
|
@ -30,6 +31,12 @@ public class ModNetwork {
|
||||||
.decoder(OpenCraftFromJeiC2SPacket::decode)
|
.decoder(OpenCraftFromJeiC2SPacket::decode)
|
||||||
.consumerNetworkThread(OpenCraftFromJeiC2SPacket::handle)
|
.consumerNetworkThread(OpenCraftFromJeiC2SPacket::handle)
|
||||||
.add();
|
.add();
|
||||||
|
|
||||||
|
CHANNEL.messageBuilder(PullFromJeiOrCraftC2SPacket.class, nextId(), NetworkDirection.PLAY_TO_SERVER)
|
||||||
|
.encoder(PullFromJeiOrCraftC2SPacket::encode)
|
||||||
|
.decoder(PullFromJeiOrCraftC2SPacket::decode)
|
||||||
|
.consumerNetworkThread(PullFromJeiOrCraftC2SPacket::handle)
|
||||||
|
.add();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int nextId() { return id++; }
|
private static int nextId() { return id++; }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
package com.extendedae_plus.network;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraftforge.network.NetworkEvent;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
|
||||||
|
import appeng.api.networking.IGrid;
|
||||||
|
import appeng.api.storage.MEStorage;
|
||||||
|
import appeng.api.storage.StorageHelper;
|
||||||
|
import appeng.api.stacks.AEItemKey;
|
||||||
|
import appeng.api.stacks.AEKey;
|
||||||
|
import appeng.api.stacks.GenericStack;
|
||||||
|
import appeng.api.networking.energy.IEnergyService;
|
||||||
|
import appeng.items.tools.powered.WirelessCraftingTerminalItem;
|
||||||
|
import appeng.items.tools.powered.WirelessTerminalItem;
|
||||||
|
import appeng.me.helpers.PlayerSource;
|
||||||
|
import appeng.menu.locator.MenuLocators;
|
||||||
|
import appeng.menu.me.crafting.CraftAmountMenu;
|
||||||
|
|
||||||
|
// ae2wtlib
|
||||||
|
import de.mari_023.ae2wtlib.wut.WUTHandler;
|
||||||
|
import de.mari_023.ae2wtlib.wut.WTDefinition;
|
||||||
|
import de.mari_023.ae2wtlib.terminal.WTMenuHost;
|
||||||
|
|
||||||
|
import com.extendedae_plus.util.WirelessTerminalLocator;
|
||||||
|
import com.extendedae_plus.util.WirelessTerminalLocator.LocatedTerminal;
|
||||||
|
import com.extendedae_plus.menu.locator.CuriosItemLocator;
|
||||||
|
|
||||||
|
public class PullFromJeiOrCraftC2SPacket {
|
||||||
|
private final GenericStack stack;
|
||||||
|
|
||||||
|
public PullFromJeiOrCraftC2SPacket(GenericStack stack) {
|
||||||
|
this.stack = stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void encode(PullFromJeiOrCraftC2SPacket msg, FriendlyByteBuf buf) {
|
||||||
|
GenericStack.writeBuffer(msg.stack, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PullFromJeiOrCraftC2SPacket decode(FriendlyByteBuf buf) {
|
||||||
|
var gs = GenericStack.readBuffer(buf);
|
||||||
|
return new PullFromJeiOrCraftC2SPacket(gs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void handle(PullFromJeiOrCraftC2SPacket msg, Supplier<NetworkEvent.Context> ctx) {
|
||||||
|
NetworkEvent.Context context = ctx.get();
|
||||||
|
context.enqueueWork(() -> {
|
||||||
|
ServerPlayer player = context.getSender();
|
||||||
|
if (player == null || msg.stack == null) return;
|
||||||
|
|
||||||
|
// 仅处理物品
|
||||||
|
AEKey what = msg.stack.what();
|
||||||
|
if (!(what instanceof AEItemKey itemKey)) return;
|
||||||
|
|
||||||
|
// 定位玩家持有/Curios 的无线终端
|
||||||
|
LocatedTerminal located = WirelessTerminalLocator.find(player);
|
||||||
|
ItemStack terminal = located.stack;
|
||||||
|
if (terminal.isEmpty()) return;
|
||||||
|
|
||||||
|
IGrid grid;
|
||||||
|
boolean usedWtHost = false;
|
||||||
|
// Curios 情况优先通过 WTMenuHost 获取网络并由其处理能量
|
||||||
|
String curiosSlotId = located.getCuriosSlotId();
|
||||||
|
int curiosIndex = located.getCuriosIndex();
|
||||||
|
WTMenuHost wtHost = null;
|
||||||
|
if (curiosSlotId != null && curiosIndex >= 0) {
|
||||||
|
String current = WUTHandler.getCurrentTerminal(terminal);
|
||||||
|
WTDefinition def = WUTHandler.wirelessTerminals.get(current);
|
||||||
|
if (def == null) return;
|
||||||
|
wtHost = def.wTMenuHostFactory().create(player, null, terminal, (p, sub) -> {});
|
||||||
|
if (wtHost == null) return;
|
||||||
|
var node = wtHost.getActionableNode();
|
||||||
|
if (node == null) return;
|
||||||
|
grid = node.getGrid();
|
||||||
|
if (grid == null) return;
|
||||||
|
if (!wtHost.drainPower()) return;
|
||||||
|
usedWtHost = true;
|
||||||
|
} else {
|
||||||
|
// 原生路径
|
||||||
|
ServerLevel level = player.serverLevel();
|
||||||
|
WirelessCraftingTerminalItem wct = terminal.getItem() instanceof WirelessCraftingTerminalItem c ? c : null;
|
||||||
|
WirelessTerminalItem wt = wct != null ? wct : (terminal.getItem() instanceof WirelessTerminalItem t ? t : null);
|
||||||
|
if (wt == null) return;
|
||||||
|
grid = wt.getLinkedGrid(terminal, level, player);
|
||||||
|
if (grid == null) return;
|
||||||
|
if (!wt.hasPower(player, 0.5, terminal)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 仅放入背包空槽位
|
||||||
|
var inv = player.getInventory();
|
||||||
|
int free = inv.getFreeSlot();
|
||||||
|
if (free == -1) return; // 背包已满
|
||||||
|
|
||||||
|
int targetMax = itemKey.toStack(1).getMaxStackSize();
|
||||||
|
IEnergyService energy = grid.getEnergyService();
|
||||||
|
MEStorage storage = grid.getStorageService().getInventory();
|
||||||
|
|
||||||
|
long extracted = StorageHelper.poweredExtraction(energy, storage, itemKey, targetMax, new PlayerSource(player));
|
||||||
|
if (extracted > 0) {
|
||||||
|
inv.setItem(free, itemKey.toStack((int) extracted));
|
||||||
|
if (!usedWtHost) {
|
||||||
|
// 扣能:与 PickFromWirelessC2SPacket 保持一致
|
||||||
|
WirelessCraftingTerminalItem wct2 = terminal.getItem() instanceof WirelessCraftingTerminalItem c2 ? c2 : null;
|
||||||
|
WirelessTerminalItem wt2 = wct2 != null ? wct2 : (terminal.getItem() instanceof WirelessTerminalItem t2 ? t2 : null);
|
||||||
|
if (wt2 != null) {
|
||||||
|
wt2.usePower(player, Math.max(0.5, extracted * 0.05), terminal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
located.commit();
|
||||||
|
player.containerMenu.broadcastChanges();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 无库存时:若可合成则打开下单界面
|
||||||
|
var craftingService = grid.getCraftingService();
|
||||||
|
if (!craftingService.isCraftable(what)) return;
|
||||||
|
|
||||||
|
if (curiosSlotId != null && curiosIndex >= 0) {
|
||||||
|
CraftAmountMenu.open(player, new CuriosItemLocator(curiosSlotId, curiosIndex), what, 1);
|
||||||
|
} else {
|
||||||
|
var hand = located.getHand();
|
||||||
|
int slot = located.getSlotIndex();
|
||||||
|
if (hand != null) {
|
||||||
|
CraftAmountMenu.open(player, MenuLocators.forHand(player, hand), what, 1);
|
||||||
|
} else if (slot >= 0) {
|
||||||
|
CraftAmountMenu.open(player, MenuLocators.forInventorySlot(slot), what, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
context.setPacketHandled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user