Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8bc766d
[IntelligenceModding/Advanced-Peripherals-Features#59] Keyboard item …
SirEndii Sep 23, 2024
6695fda
Remove custom indentation
SirEndii Sep 23, 2024
027787b
Binding/Unbinding for the keyboard
SirEndii Sep 23, 2024
19f4de9
Use translatable components and add name and description for the keyb…
SirEndii Sep 23, 2024
c507f0a
Removed owner tag from the memory card
SirEndii Sep 23, 2024
ab6a8cd
Key press/Char typed sync to the computer logic
SirEndii Sep 24, 2024
5af40a8
The keyboard is now a working module, it currently uses the hotkey mo…
SirEndii Sep 25, 2024
b94b8be
Mouse events for the keyboard module
SirEndii Sep 26, 2024
9ba1214
Fixed an issue where the keyboard does not bound to the glasses when …
SirEndii Sep 26, 2024
e8f70d7
Render a little info text when the player is using the keyboard
SirEndii Sep 28, 2024
1b147a3
Preven JEI/REI/EMI from rendering in the keyboard screen
SirEndii Sep 30, 2024
48ce6e5
Merge branch 'dev/0.8' into feat/keyboard
SirEndii Jan 16, 2025
b689497
checkstyle
SirEndii Jan 16, 2025
36193be
Simplify KeyboardScreen
SirEndii Jan 16, 2025
5e439b9
Sort ClientRegistry.java
SirEndii Jan 17, 2025
a7c5984
Merge branch 'dev/0.8' into feat/keyboard
SirEndii Jan 17, 2025
f5efd86
Add language entries
SirEndii Jan 17, 2025
25cb800
Merge branch 'dev/0.8' of https://github.com/IntelligenceModding/Adva…
zyxkad Mar 15, 2025
256cf0e
make keyboard based on computer ID instead of position
zyxkad Mar 15, 2025
5251139
run runData
zyxkad Mar 15, 2025
3549dd9
implement keyboard mouse capture mode
zyxkad Mar 15, 2025
d6dd79b
fix styles
zyxkad Mar 15, 2025
21e7aeb
Merge pull request #719 from zyxkad/player-rotate-handle-feature
SirEndii Mar 19, 2025
58a92cd
make lock final
zyxkad Mar 19, 2025
cf93b69
fix keyboard does not work in multiplayer
zyxkad Jun 19, 2025
0e90294
fix keyboard_close fires with delay
zyxkad Jun 19, 2025
b471dd3
remove unused import
zyxkad Jun 19, 2025
4978a6b
Merge pull request #751 from zyxkad/feat/keyboard
SirEndii Sep 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// 1.19.2 2025-01-20T07:59:27.474151 Tags for minecraft:item
// 1.19.2 2025-03-15T16:18:50.46663 Tags for minecraft:item
de4b4f45ec18b2b1f0db1c36882981042e20ee23 data/advancedperipherals/tags/items/p2p_attunements/cable_p2p_tunnel.json
72eba3b11f69e16c87488f7c4ba7cfdad42c378e data/advancedperipherals/tags/items/smart_glasses.json
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// 1.19.2 2024-05-28T14:53:16.655175 AP POI Type Tags
// 1.19.2 2025-03-15T16:18:50.465796 AP POI Type Tags
d3d6b837660a4e213f287ad9d11e12368b90cd8e data/minecraft/tags/point_of_interest_type/acquirable_job_site.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// 1.19.2 2024-05-28T14:53:16.655476 Turtle Upgrades
// 1.19.2 2025-03-15T16:18:50.466321 Turtle Upgrades
b8f19ae0fb5bb898facc08e3787e0f96c8211881 data/advancedperipherals/computercraft/turtle_upgrades/chatty_turtle.json
fe98c60e7d61139aacf2d0872873e610aac8a37b data/advancedperipherals/computercraft/turtle_upgrades/chunky_turtle.json
ae619da638ad89d7302d832d6c09e2c87401c539 data/advancedperipherals/computercraft/turtle_upgrades/compass_turtle.json
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// 1.19.2 2025-01-16T15:46:41.860623 LootTables
// 1.19.2 2025-03-15T16:18:50.465594 LootTables
618b63c020ab64890c8a2d2506dd61cd30259a44 data/advancedperipherals/loot_tables/blocks/block_reader.json
0923665563d05307a7fa7d711a2d7a994a31eb6e data/advancedperipherals/loot_tables/blocks/chat_box.json
bf2a80256cfba0bd8c0283d493882e5816882f1f data/advancedperipherals/loot_tables/blocks/colony_integrator.json
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// 1.19.2 2024-05-28T14:53:16.657381 Recipes
// 1.19.2 2025-03-15T16:18:50.466743 Recipes
045608027e4a5ea2d7dee7f402346b8e69f21675 data/advancedperipherals/advancements/recipes/advancedperipheralstab/armor/smart_glasses_netherite.json
db2dada2fdf42ca1bbf47f1eb075d1f9de89dfa8 data/advancedperipherals/advancements/recipes/advancedperipheralstab/block_reader.json
77c55e8500be4a344ca563a8bf7642257cdc7b8b data/advancedperipherals/advancements/recipes/advancedperipheralstab/chat_box.json
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// 1.19.2 2025-01-25T19:46:21.23515 Pocket Computer Upgrades
// 1.19.2 2025-03-15T16:18:50.46512 Pocket Computer Upgrades
b672635324c0df354e587efc81d0b19a581eae2f data/advancedperipherals/computercraft/pocket_upgrades/chatty_pocket.json
30b8f663613c7ce77048fd69631afcc11a682276 data/advancedperipherals/computercraft/pocket_upgrades/colony_pocket.json
661dc77bd0442bfb2a5ed80cff271071817bb22d data/advancedperipherals/computercraft/pocket_upgrades/distance_pocket.json
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// 1.19.2 2024-05-28T14:53:16.658228 Block States: advancedperipherals
// 1.19.2 2025-03-15T16:18:50.466039 Block States: advancedperipherals
5e28ce1be9a6996d982641e5df1fa7162090b8cc assets/advancedperipherals/blockstates/block_reader.json
f42bdde60f84fdb312f7cf3b2be461d9c11ebdc8 assets/advancedperipherals/blockstates/chat_box.json
1227aa092fcf1327547ace6ccc9db230e45891b0 assets/advancedperipherals/blockstates/colony_integrator.json
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// 1.19.2 2025-01-25T19:46:21.234203 Languages: en_us
e858500d72e9279f0fe0e8b2d03f94469c8d1f65 assets/advancedperipherals/lang/en_us.json
// 1.19.2 2025-03-15T16:18:50.465918 Languages: en_us
fe52123263b91f49093d74278e8709484e4dfe59 assets/advancedperipherals/lang/en_us.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// 1.19.2 2025-01-16T15:46:41.859383 Block tags
// 1.19.2 2025-03-15T16:18:50.466493 Block tags
e1f71dcb4f9e7e36e29b0ad09d6520dc3adfa4a6 data/forge/tags/blocks/needs_wood_tool.json
03322cd493601129eaad6ba7c2a6d808023dfac1 data/minecraft/tags/blocks/mineable/pickaxe.json
277fe59db076a3eab3c97080531ad345f8ca5f3d data/minecraft/tags/blocks/needs_iron_tool.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"item.advancedperipherals.end_automata_core": "End Automata Core",
"item.advancedperipherals.hotkey_module": "Hotkey Module",
"item.advancedperipherals.husbandry_automata_core": "Husbandry Automata Core",
"item.advancedperipherals.keyboard": "Wireless Keyboard",
"item.advancedperipherals.memory_card": "Memory Card",
"item.advancedperipherals.nightvision_module": "Night Vision Module",
"item.advancedperipherals.overlay_module": "Overlay Module",
Expand All @@ -49,6 +50,8 @@
"item.advancedperipherals.smart_glasses": "Smart Glasses",
"item.advancedperipherals.smart_glasses_interface": "Smart Glasses Interface",
"item.advancedperipherals.smart_glasses_netherite": "Netherite reinforced Smart Glasses",
"item.advancedperipherals.tooltip.binding.bound_to": "&7Bound to &b%s&7.",
"item.advancedperipherals.tooltip.binding.bound_to_glasses": "&7Bound to Glasses with id &b%s&7.",
"item.advancedperipherals.tooltip.block_reader": "&7Reads nbt data of blocks to interact with blocks which do not have computer support.",
"item.advancedperipherals.tooltip.chat_box": "&7Interacts with the ingame chat, can read and write messages.",
"item.advancedperipherals.tooltip.chunk_controller": "&7A crafting ingredient for the Chunky Turtle.",
Expand All @@ -63,7 +66,6 @@
"item.advancedperipherals.tooltip.inventory_manager": "&7This block is able to send or receive specific items from a player inventory.",
"item.advancedperipherals.tooltip.me_bridge": "&7The ME Bridge interacts with Applied Energistics to manage your items.",
"item.advancedperipherals.tooltip.memory_card": "&7Can save the rights of a player to use it in an inventory manager.",
"item.advancedperipherals.tooltip.memory_card.bound": "&7Bound to &b%s&7.",
"item.advancedperipherals.tooltip.nbt_storage": "&7Acts like a storage disk. Can store nbt based data.",
"item.advancedperipherals.tooltip.overpowered_end_automata_core": "&7Improved version of the end automata core, that provides some overpowered uses! Be careful, the upgrade is very fragile.",
"item.advancedperipherals.tooltip.overpowered_husbandry_automata_core": "&7Improved version of the husbandry automata core, that provides some overpowered uses! Be careful, the upgrade is very fragile.",
Expand All @@ -84,9 +86,13 @@
"pocket.advancedperipherals.environment_pocket": "Environment",
"pocket.advancedperipherals.geoscanner_pocket": "Geo",
"pocket.advancedperipherals.player_pocket": "Player Detector",
"text.advancedperipherals.added_player": "Added you to the memory card",
"text.advancedperipherals.automata_core.feed_by_player": "You're trying to feed an entity to a soul, but your own body refuses to do this. Maybe something more mechanical can do this?",
"text.advancedperipherals.removed_player": "Cleared the memory card",
"text.advancedperipherals.bind_keyboard": "Bounded the keyboard to %s",
"text.advancedperipherals.bind_memorycard": "Bounded the memory card to you",
"text.advancedperipherals.cleared_keyboard": "Cleared the keyboard",
"text.advancedperipherals.cleared_memorycard": "Cleared the memory card",
"text.advancedperipherals.keyboard.close": "Press ESC to close the Keyboard Screen",
"text.advancedperipherals.keyboard_notbound": "The keyboard it not bound",
"text.advancedperipherals.saddle_turtle.dismount_hint": "Controlling %1$s. Press %2$s and %3$s to dismount.",
"text.advancedperipherals.smart_glasses.modules": "Modules",
"text.advancedperipherals.smart_glasses.peripherals": "Peripherals",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"values": [
"advancedperipherals:peripheral_casing",
"advancedperipherals:colony_integrator"
"advancedperipherals:peripheral_casing"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import de.srendi.advancedperipherals.AdvancedPeripherals;
import de.srendi.advancedperipherals.client.renderer.DistanceDetectorRenderer;
import de.srendi.advancedperipherals.client.screens.InventoryManagerScreen;
import de.srendi.advancedperipherals.client.screens.KeyboardScreen;
import de.srendi.advancedperipherals.client.screens.SaddleTurtleScreen;
import de.srendi.advancedperipherals.client.screens.SmartGlassesScreen;
import de.srendi.advancedperipherals.client.smartglasses.OverlayModuleOverlay;
Expand Down Expand Up @@ -42,6 +43,7 @@ public static void registerModels(ModelEvent.RegisterAdditional event) {
@SubscribeEvent
public static void onClientSetup(FMLClientSetupEvent event) {
MenuScreens.register(APContainerTypes.INVENTORY_MANAGER_CONTAINER.get(), InventoryManagerScreen::new);
MenuScreens.register(APContainerTypes.KEYBOARD_CONTAINER.get(), KeyboardScreen::new);
MenuScreens.register(APContainerTypes.SMART_GLASSES_CONTAINER.get(), SmartGlassesScreen::new);

ComputerCraftAPIClient.registerTurtleUpgradeModeller(CCRegistration.CHUNKY_TURTLE.get(), TurtleUpgradeModeller.flatItem());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package de.srendi.advancedperipherals.client;

import de.srendi.advancedperipherals.AdvancedPeripherals;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Mod.EventBusSubscriber(value = Dist.CLIENT, modid = AdvancedPeripherals.MOD_ID)
public class ClientWorker {

private static final Map<String, Runnable> tasks = new ConcurrentHashMap<>();

/**
* This method will put a task to current tick's end.
* If a task with given identifier is already exists, the task will be replaced.
*/
public static void put(final String id, final Runnable task) {
tasks.put(id, task);
}

@SubscribeEvent
public static void clientTick(TickEvent.ClientTickEvent event) {
if (event.phase == TickEvent.Phase.END) {
tasks.forEach((id, runnable) -> {
tasks.remove(id, runnable);
runnable.run();
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
package de.srendi.advancedperipherals.client.screens;

import com.mojang.blaze3d.platform.InputConstants;
import com.mojang.blaze3d.platform.Window;
import com.mojang.blaze3d.vertex.PoseStack;
import dan200.computercraft.client.gui.ClientInputHandler;
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.computer.core.InputHandler;
import de.srendi.advancedperipherals.client.ClientWorker;
import de.srendi.advancedperipherals.common.container.KeyboardContainer;
import de.srendi.advancedperipherals.common.network.APNetworking;
import de.srendi.advancedperipherals.common.network.toserver.KeyboardMouseClickPacket;
import de.srendi.advancedperipherals.common.network.toserver.KeyboardMouseMovePacket;
import de.srendi.advancedperipherals.common.network.toserver.KeyboardMouseScrollPacket;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.MenuAccess;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW;

/**
* A simple screen but without any rendering calls. Used to unlock the mouse so we can freely write stuff
* <p>
* We just create a terminal which is used to forward all the key presses and mouse clicks but we don't render it.
*/
public class KeyboardScreen extends Screen implements MenuAccess<KeyboardContainer> {

protected final KeyboardContainer keyboardContainer;
protected final InputHandler input;
private final Terminal terminalData;
private WidgetTerminal terminal;
private MouseState mouseState = MouseState.RELEASED;
private boolean captureMouse;
private boolean regrabingMouse;
private final byte[] lastPosLock = new byte[0];
private double lastX = 0;
private double lastY = 0;
private double lastScroll = 0;

public KeyboardScreen(KeyboardContainer keyboardContainer, Inventory inv, Component titleIn) {
super(titleIn);
this.keyboardContainer = keyboardContainer;
this.input = new ClientInputHandler(keyboardContainer);
this.terminalData = new Terminal(0, 0, false);
}

@Override
public KeyboardContainer getMenu() {
return this.keyboardContainer;
}

@Override
public void render(@NotNull PoseStack poseStack, int x, int y, float partialTicks) {
super.render(poseStack, x, y, partialTicks);

Minecraft minecraft = Minecraft.getInstance();
float scale = 2f;
int screenWidth = minecraft.getWindow().getGuiScaledWidth();
// Make the text a bit smaller on small screens
if (screenWidth <= 1080)
scale = 1f;

poseStack.scale(scale, scale, 1);
Component text = Component.translatable("text.advancedperipherals.keyboard.close");
float textX = (screenWidth / 2f - minecraft.font.width(text) * scale / 2f) / scale;
minecraft.font.drawShadow(poseStack, text, textX, 1, 0xFFFFFF);
}

@Override
protected void init() {
if (this.isCapturingMouse()) {
this.grabMouse();
} else {
this.grabMouseWithControl();
}
this.passEvents = true;
KeyMapping.releaseAll();

super.init();
this.minecraft.keyboardHandler.setSendRepeatsToGui(true);

this.terminal = addWidget(new WidgetTerminal(terminalData, new ClientInputHandler(this.keyboardContainer), 0, 0));
this.terminal.visible = false;
this.terminal.active = false;
setFocused(this.terminal);
}

@Override
public final void removed() {
if (this.regrabingMouse) {
return;
}
super.removed();
if (this.minecraft.player != null) {
this.keyboardContainer.removed(this.minecraft.player);
}
this.minecraft.keyboardHandler.setSendRepeatsToGui(false);
}

@Override
public void onClose() {
// Don't allow closing using standard keys like E. Closing using ESCAPE is still possible due to the keyPressed method
}

@Override
public boolean isPauseScreen() {
return false;
}

@Override
public void mouseMoved(double x, double y) {
if (this.mouseState != MouseState.CAPTURE) {
return;
}
ClientWorker.put("mouse_move", () -> {
synchronized (this.lastPosLock) {
double dx = x - this.lastX;
double dy = y - this.lastY;
APNetworking.sendToServer(new KeyboardMouseMovePacket(dx, dy));
this.lastX = x;
this.lastY = y;
}
});
}

@Override
public boolean mouseClicked(double x, double y, int button) {
if (this.mouseState != MouseState.CAPTURE) {
return false;
}
APNetworking.sendToServer(new KeyboardMouseClickPacket(button, false));
return true;
}

@Override
public boolean mouseReleased(double x, double y, int button) {
if (this.mouseState != MouseState.CAPTURE) {
return false;
}
APNetworking.sendToServer(new KeyboardMouseClickPacket(button, true));
return true;
}

@Override
public boolean mouseScrolled(double x, double y, double direction) {
this.lastScroll += direction;
int scrolled = (int) this.lastScroll;
if (scrolled == 0) {
return true;
}
if (this.mouseState == MouseState.CAPTURE) {
ClientWorker.put("mouse_scroll", () -> {
if (this.mouseState != MouseState.CAPTURE) {
return;
}
this.lastScroll -= scrolled;
APNetworking.sendToServer(new KeyboardMouseScrollPacket(scrolled));
});
} else {
this.lastScroll -= scrolled;
minecraft.player.getInventory().swapPaint(scrolled);
}
return true;
}

@Override
public final boolean keyPressed(int key, int scancode, int modifiers) {
if (key == GLFW.GLFW_KEY_ESCAPE) {
if (this.minecraft.player != null) {
this.minecraft.player.closeContainer();
} else {
super.onClose();
}
return true;
}
// Forward the tab key to the terminal, rather than moving between controls.
if (key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminal) {
return getFocused().keyPressed(key, scancode, modifiers);
}

return super.keyPressed(key, scancode, modifiers);
}

public boolean isCapturingMouse() {
return this.captureMouse;
}

public void setCaptureMouse(boolean enable) {
this.captureMouse = enable;
if (enable) {
this.grabMouse();
} else {
this.grabMouseWithControl();
}
}

private void grabMouseWithControl() {
if (this.mouseState == MouseState.NORMAL) {
return;
}
this.releaseMouse();
this.regrabingMouse = true;
this.minecraft.mouseHandler.grabMouse();
this.regrabingMouse = false;
this.minecraft.screen = this;
this.mouseState = MouseState.NORMAL;
}

private void grabMouse() {
if (this.minecraft.mouseHandler.isMouseGrabbed()) {
this.minecraft.mouseHandler.releaseMouse();
}
Window window = this.minecraft.getWindow();
synchronized (this.lastPosLock) {
this.lastX = window.getScreenWidth() / 2;
this.lastY = window.getScreenHeight() / 2;
InputConstants.grabOrReleaseMouse(window.getWindow(), InputConstants.CURSOR_DISABLED, this.lastX, this.lastY);
}
this.mouseState = MouseState.CAPTURE;
}

private void releaseMouse() {
if (this.mouseState == MouseState.RELEASED) {
return;
}
if (this.minecraft.mouseHandler.isMouseGrabbed()) {
this.minecraft.mouseHandler.releaseMouse();
return;
}
Window window = this.minecraft.getWindow();
synchronized (this.lastPosLock) {
this.lastX = window.getScreenWidth() / 2;
this.lastY = window.getScreenHeight() / 2;
InputConstants.grabOrReleaseMouse(window.getWindow(), InputConstants.CURSOR_NORMAL, this.lastX, this.lastY);
}
this.mouseState = MouseState.RELEASED;
}

private enum MouseState {
RELEASED, NORMAL, CAPTURE
}
}
Loading
Loading