diff --git a/src/main/java/appeng/core/AppEngBase.java b/src/main/java/appeng/core/AppEngBase.java index 175c0d22b06..e019f393500 100644 --- a/src/main/java/appeng/core/AppEngBase.java +++ b/src/main/java/appeng/core/AppEngBase.java @@ -59,6 +59,7 @@ import appeng.api.stacks.AEKeyType; import appeng.api.stacks.AEKeyTypes; import appeng.api.stacks.AEKeyTypesInternal; +import appeng.core.definitions.AEAttachmentTypes; import appeng.core.definitions.AEBlocks; import appeng.core.definitions.AEItems; import appeng.core.definitions.AEParts; @@ -123,6 +124,7 @@ public AppEngBase(IEventBus modEventBus) { AEComponents.DR.register(modEventBus); InitStructures.register(modEventBus); + AEAttachmentTypes.register(modEventBus); modEventBus.addListener(this::registerRegistries); modEventBus.addListener(MainCreativeTab::initExternal); modEventBus.addListener(InitNetwork::init); diff --git a/src/main/java/appeng/core/AppEngClient.java b/src/main/java/appeng/core/AppEngClient.java index 53baffdd6d3..dbb4506b305 100644 --- a/src/main/java/appeng/core/AppEngClient.java +++ b/src/main/java/appeng/core/AppEngClient.java @@ -87,9 +87,11 @@ import appeng.client.render.effects.ParticleTypes; import appeng.client.render.effects.VibrantFX; import appeng.client.render.overlay.OverlayManager; +import appeng.core.definitions.AEAttachmentTypes; import appeng.core.definitions.AEBlocks; import appeng.core.network.ServerboundPacket; import appeng.core.network.serverbound.MouseWheelPacket; +import appeng.core.network.serverbound.PartPlacementOppositePacket; import appeng.helpers.IMouseWheelItem; import appeng.hooks.BlockAttackHook; import appeng.hooks.RenderBlockOutlineHook; @@ -132,6 +134,10 @@ public class AppEngClient extends AppEngBase { "key.ae2.mouse_wheel_item_modifier", KeyConflictContext.IN_GAME, InputConstants.Type.KEYSYM, InputConstants.KEY_LSHIFT, "key.ae2.category"); + private static final KeyMapping PART_PLACEMENT_OPPOSITE = new KeyMapping( + "key.ae2.part_placement_opposite", KeyConflictContext.IN_GAME, InputConstants.Type.KEYSYM, + InputConstants.KEY_LCONTROL, "key.ae2.category"); + private final Guide guide; public AppEngClient(IEventBus modEventBus) { @@ -231,6 +237,7 @@ private void registerHotkeys(RegisterKeyMappingsEvent e) { e.register(OpenGuideHotkey.getHotkey()); } e.register(MOUSE_WHEEL_ITEM_MODIFIER); + e.register(PART_PLACEMENT_OPPOSITE); Hotkeys.finalizeRegistration(e::register); } @@ -271,6 +278,7 @@ private void clientSetup(FMLClientSetupEvent event) { }); NeoForge.EVENT_BUS.addListener(this::wheelEvent); + NeoForge.EVENT_BUS.addListener(this::ctrlEvent); NeoForge.EVENT_BUS.register(OverlayManager.getInstance()); } @@ -330,6 +338,18 @@ private void wheelEvent(final InputEvent.MouseScrollingEvent me) { } } + private void ctrlEvent(InputEvent.Key event) { + if (event.getKey() == PART_PLACEMENT_OPPOSITE.getKey().getValue()) { + var player = Minecraft.getInstance().player; + + if (player != null) { + var isDown = event.getAction() == InputConstants.PRESS; + player.setData(AEAttachmentTypes.HOLDING_CTRL, isDown); + PacketDistributor.sendToServer(new PartPlacementOppositePacket(isDown)); + } + } + } + public boolean shouldAddParticles(RandomSource r) { return switch (Minecraft.getInstance().options.particles().get()) { case ALL -> true; diff --git a/src/main/java/appeng/core/definitions/AEAttachmentTypes.java b/src/main/java/appeng/core/definitions/AEAttachmentTypes.java new file mode 100644 index 00000000000..734ece33c1e --- /dev/null +++ b/src/main/java/appeng/core/definitions/AEAttachmentTypes.java @@ -0,0 +1,22 @@ +package appeng.core.definitions; + +import java.util.function.Supplier; + +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.attachment.AttachmentType; +import net.neoforged.neoforge.registries.DeferredRegister; +import net.neoforged.neoforge.registries.NeoForgeRegistries; + +import appeng.core.AppEng; + +public final class AEAttachmentTypes { + private static final DeferredRegister> ATTACHMENT_TYPES = DeferredRegister + .create(NeoForgeRegistries.ATTACHMENT_TYPES, AppEng.MOD_ID); + + public static final Supplier> HOLDING_CTRL = ATTACHMENT_TYPES.register("ctrl", + () -> AttachmentType.builder(() -> false).build()); + + public static void register(IEventBus modEventBus) { + ATTACHMENT_TYPES.register(modEventBus); + } +} diff --git a/src/main/java/appeng/core/network/InitNetwork.java b/src/main/java/appeng/core/network/InitNetwork.java index 516b2fbea33..3a9a42bc6ab 100644 --- a/src/main/java/appeng/core/network/InitNetwork.java +++ b/src/main/java/appeng/core/network/InitNetwork.java @@ -36,6 +36,7 @@ import appeng.core.network.serverbound.MEInteractionPacket; import appeng.core.network.serverbound.MouseWheelPacket; import appeng.core.network.serverbound.PartLeftClickPacket; +import appeng.core.network.serverbound.PartPlacementOppositePacket; import appeng.core.network.serverbound.SelectKeyTypePacket; import appeng.core.network.serverbound.SwapSlotsPacket; import appeng.core.network.serverbound.SwitchGuisPacket; @@ -78,6 +79,7 @@ public static void init(RegisterPayloadHandlersEvent event) { serverbound(registrar, SelectKeyTypePacket.TYPE, SelectKeyTypePacket.STREAM_CODEC); serverbound(registrar, SwapSlotsPacket.TYPE, SwapSlotsPacket.STREAM_CODEC); serverbound(registrar, SwitchGuisPacket.TYPE, SwitchGuisPacket.STREAM_CODEC); + serverbound(registrar, PartPlacementOppositePacket.TYPE, PartPlacementOppositePacket.STREAM_CODEC); // Bidirectional bidirectional(registrar, ConfigValuePacket.TYPE, ConfigValuePacket.STREAM_CODEC); diff --git a/src/main/java/appeng/core/network/serverbound/PartPlacementOppositePacket.java b/src/main/java/appeng/core/network/serverbound/PartPlacementOppositePacket.java new file mode 100644 index 00000000000..470815f37ed --- /dev/null +++ b/src/main/java/appeng/core/network/serverbound/PartPlacementOppositePacket.java @@ -0,0 +1,40 @@ +package appeng.core.network.serverbound; + +import org.jetbrains.annotations.NotNull; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.server.level.ServerPlayer; + +import appeng.core.definitions.AEAttachmentTypes; +import appeng.core.network.CustomAppEngPayload; +import appeng.core.network.ServerboundPacket; + +public record PartPlacementOppositePacket(boolean keyDown) implements ServerboundPacket { + public static final StreamCodec STREAM_CODEC = StreamCodec + .ofMember( + PartPlacementOppositePacket::write, + PartPlacementOppositePacket::decode); + + public static final Type TYPE = CustomAppEngPayload.createType("ctrl_down"); + + @NotNull + @Override + public Type type() { + return TYPE; + } + + public static PartPlacementOppositePacket decode(RegistryFriendlyByteBuf buf) { + var keyDown = buf.readBoolean(); + return new PartPlacementOppositePacket(keyDown); + } + + public void write(RegistryFriendlyByteBuf data) { + data.writeBoolean(keyDown); + } + + @Override + public void handleOnServer(ServerPlayer player) { + player.setData(AEAttachmentTypes.HOLDING_CTRL, keyDown); + } +} diff --git a/src/main/java/appeng/datagen/providers/localization/LocalizationProvider.java b/src/main/java/appeng/datagen/providers/localization/LocalizationProvider.java index 5ca30483507..a321d419960 100644 --- a/src/main/java/appeng/datagen/providers/localization/LocalizationProvider.java +++ b/src/main/java/appeng/datagen/providers/localization/LocalizationProvider.java @@ -128,6 +128,7 @@ private void generateLocalizations() { add("key.ae2.wireless_terminal", "Open Wireless Terminal"); add("key.ae2.guide", "Open Guide for Items"); add("key.ae2.mouse_wheel_item_modifier", "Modifier for Mouse-Wheel Items"); + add("key.ae2.part_placement_opposite", "Place Parts on Opposite Side"); add("key.toggle_focus.desc", "Toggle search box focus"); add("stat.ae2.items_extracted", "Items extracted from ME Storage"); add("stat.ae2.items_inserted", "Items added to ME Storage"); diff --git a/src/main/java/appeng/parts/PartPlacement.java b/src/main/java/appeng/parts/PartPlacement.java index 2ed2738b46c..e71be6294e1 100644 --- a/src/main/java/appeng/parts/PartPlacement.java +++ b/src/main/java/appeng/parts/PartPlacement.java @@ -21,12 +21,12 @@ import appeng.api.parts.IPartItem; import appeng.api.parts.PartHelper; import appeng.core.AELog; +import appeng.core.definitions.AEAttachmentTypes; import appeng.parts.networking.CablePart; import appeng.util.Platform; import appeng.util.SettingsFrom; public class PartPlacement { - public static InteractionResult place(UseOnContext context) { var player = context.getPlayer(); @@ -136,6 +136,10 @@ public static Placement getPartPlacement(@Nullable Player player, return replaceCablePlacement; } + if (player != null) { + side = player.getData(AEAttachmentTypes.HOLDING_CTRL) ? side.getOpposite() : side; + } + if (canPlacePartOnBlock(player, level, partStack, pos, side)) { return new Placement(pos, side); }