From ccf3e14cd4018b3d2a3a5b4421e4c4cea57f28c4 Mon Sep 17 00:00:00 2001 From: Laconiq Date: Sat, 11 Apr 2026 19:43:00 +0200 Subject: [PATCH] Add customizable camera keybindings in Settings > Controls Camera movement keys (WASD, Space, Shift) were hardcoded in BrickBench.java. This adds them as rebindable entries in the Controls settings panel, using the existing BrickbenchBindings and HotkeyButton infrastructure. Changes: - Add 6 camera bindings (cam_forward, etc.) to BrickbenchBindings - Replace hardcoded BindController calls with reapplyCameraBindings() - Show camera bindings in Controls panel, exclude from Key Bindings - Apply binding changes immediately via HotkeyButton callback - Fix NumberFormatException crash when FOV config is empty - Make settings panels scrollable --- src/com/opengg/loader/BrickBench.java | 8 ++--- .../loader/editor/BrickbenchBindings.java | 24 +++++++++++++++ .../editor/components/HotkeyButton.java | 3 ++ .../loader/editor/windows/SettingsDialog.java | 29 ++++++++++++++++--- 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/com/opengg/loader/BrickBench.java b/src/com/opengg/loader/BrickBench.java index 21f7360..6950371 100644 --- a/src/com/opengg/loader/BrickBench.java +++ b/src/com/opengg/loader/BrickBench.java @@ -491,12 +491,8 @@ public void setup() { Light.createDirectional(Quaternionf.createXYZ(new Vector3f(0, 0, -0.5f)), new Vector3f(1, 1, 1)))); WorldEngine.getCurrent().attach(TCSHookManager.enemyManager = new HookCharacterManager()); - BindController.addBind(ControlType.KEYBOARD, "forward", KEY_W); - BindController.addBind(ControlType.KEYBOARD, "backward", KEY_S); - BindController.addBind(ControlType.KEYBOARD, "left", KEY_A); - BindController.addBind(ControlType.KEYBOARD, "right", KEY_D); - BindController.addBind(ControlType.KEYBOARD, "up", KEY_SPACE); - BindController.addBind(ControlType.KEYBOARD, "down", KEY_LEFT_SHIFT); + // Load camera bindings from BrickbenchBindings (customizable via Settings > Controls) + BrickbenchBindings.reapplyCameraBindings(); RenderEngine.setProjectionData(ProjectionData.getPerspective(110, 0.2f, 3000f)); diff --git a/src/com/opengg/loader/editor/BrickbenchBindings.java b/src/com/opengg/loader/editor/BrickbenchBindings.java index ff07b04..8edcdf8 100644 --- a/src/com/opengg/loader/editor/BrickbenchBindings.java +++ b/src/com/opengg/loader/editor/BrickbenchBindings.java @@ -35,6 +35,15 @@ public Binding(String inActionName, String inDisplayName, KeyStroke inKeyStroke) public static void load(String path){ + // Camera movement bindings (shown in Controls panel) + keyMap.put("cam_forward", new Binding("cam_forward","Camera Forward", KeyStroke.getKeyStroke(KeyEvent.VK_W, 0))); + keyMap.put("cam_backward", new Binding("cam_backward","Camera Backward", KeyStroke.getKeyStroke(KeyEvent.VK_S, 0))); + keyMap.put("cam_left", new Binding("cam_left","Camera Left", KeyStroke.getKeyStroke(KeyEvent.VK_A, 0))); + keyMap.put("cam_right", new Binding("cam_right","Camera Right", KeyStroke.getKeyStroke(KeyEvent.VK_D, 0))); + keyMap.put("cam_up", new Binding("cam_up","Camera Up", KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0))); + keyMap.put("cam_down", new Binding("cam_down","Camera Down", KeyStroke.getKeyStroke(KeyEvent.VK_SHIFT, 0))); + + // Hook bindings (shown in Key Bindings panel) keyMap.put("teleport1", new Binding("teleport1","Teleport Player 1", KeyStroke.getKeyStroke(KeyEvent.VK_T,0))); keyMap.put("teleport2", new Binding("teleport2","Teleport Player 2", KeyStroke.getKeyStroke(KeyEvent.VK_T, KeyEvent.CTRL_MASK | KeyEvent.CTRL_DOWN_MASK))); keyMap.put("loadMap1", new Binding("loadMap1","Load Map", KeyStroke.getKeyStroke(KeyEvent.VK_F12, 0))); @@ -63,6 +72,21 @@ public static void load(String path){ } } + private static final java.util.Map CAM_ACTION_MAP = java.util.Map.of( + "cam_forward","forward", "cam_backward","backward", + "cam_left","left", "cam_right","right", + "cam_up","up", "cam_down","down"); + + public static void reapplyCameraBindings() { + for (var entry : CAM_ACTION_MAP.entrySet()) { + var bind = getOpenGGKeycode(entry.getKey()); + if (bind != null) { + com.opengg.core.engine.BindController.addBind( + new com.opengg.core.io.Bind(com.opengg.core.io.ControlType.KEYBOARD, entry.getValue(), bind.x())); + } + } + } + public static void save(String path){ try(BufferedWriter writer = new BufferedWriter( new FileWriter( path ))) { for(Map.Entry entry : BrickbenchBindings.keyMap.entrySet()){ diff --git a/src/com/opengg/loader/editor/components/HotkeyButton.java b/src/com/opengg/loader/editor/components/HotkeyButton.java index 03e7eb0..0962912 100644 --- a/src/com/opengg/loader/editor/components/HotkeyButton.java +++ b/src/com/opengg/loader/editor/components/HotkeyButton.java @@ -51,6 +51,9 @@ public void selectEvent(boolean b){ public void setBinding(KeyStroke stroke){ binding.keystroke = stroke; BrickbenchBindings.keyMap.put(binding.actionName, binding); + if (binding.actionName.startsWith("cam_")) { + BrickbenchBindings.reapplyCameraBindings(); + } setText(getKeyText()); setSelected(false); } diff --git a/src/com/opengg/loader/editor/windows/SettingsDialog.java b/src/com/opengg/loader/editor/windows/SettingsDialog.java index abba136..a8b7b17 100644 --- a/src/com/opengg/loader/editor/windows/SettingsDialog.java +++ b/src/com/opengg/loader/editor/windows/SettingsDialog.java @@ -110,7 +110,14 @@ private void useControlsPanel(){ String.valueOf(sensitivity.getValue()/20f))); sensitivity.setToolTipText("Sets the mouse sensitivity for the camera."); - var fov = new JSlider(JSlider.HORIZONTAL, 30, 150, Integer.parseInt(Configuration.get("fov"))); + int iFov = 110; + try { + iFov = Integer.parseInt(Configuration.get("fov")); + } catch (NumberFormatException e) { + GGConsole.warning("Invalid FOV in config: " + Configuration.get("fov")); + } + + var fov = new JSlider(JSlider.HORIZONTAL, 30, 150, iFov); fov.setPaintTicks(true); fov.setPaintLabels(true); fov.setMajorTickSpacing(20); @@ -136,6 +143,13 @@ private void useControlsPanel(){ addItem("Lock camera", camLock); addCompactItem("Retain position when loading new maps", retainPos); + // Camera keybindings + for (var entry : BrickbenchBindings.keyMap.entrySet()) { + if (entry.getKey().startsWith("cam_")) { + addItem(entry.getValue().displayName, new HotkeyButton(entry.getValue(), this)); + } + } + this.settingsPanel.validate(); this.settingsPanel.repaint(); this.validate(); @@ -292,7 +306,9 @@ private void useHotkeysPanel(){ resetPanel(); for(Map.Entry entry : BrickbenchBindings.keyMap.entrySet()){ - addItem(entry.getValue().displayName, new HotkeyButton(entry.getValue(), this)); + if (!entry.getKey().startsWith("cam_")) { + addItem(entry.getValue().displayName, new HotkeyButton(entry.getValue(), this)); + } } this.settingsPanel.validate(); @@ -301,11 +317,16 @@ private void useHotkeysPanel(){ } private void resetPanel(){ - settingsPanel.remove(currentSettingsPanel); + settingsPanel.removeAll(); currentSettingsPanel = new JPanel(); - settingsPanel.add(currentSettingsPanel); currentSettingsPanel.setLayout(new MigLayout("wrap 2, fillx, align left top", "[]10[]", "[]15[]")); + + var scrollPane = new JScrollPane(currentSettingsPanel); + scrollPane.setBorder(null); + scrollPane.getVerticalScrollBar().setUnitIncrement(16); + settingsPanel.setLayout(new BorderLayout()); + settingsPanel.add(scrollPane, BorderLayout.CENTER); } public void addItem(String label, JComponent component){