Files
common/src/main/java/org/saturnclient/feature/features/KeystrokesFeature.java
T
2026-03-20 21:03:53 +01:00

167 lines
5.9 KiB
Java

package org.saturnclient.feature.features;
import org.saturnclient.common.provider.Providers;
import org.saturnclient.config.property.BoolProperty;
import org.saturnclient.config.property.ColorProperty;
import org.saturnclient.config.property.Property;
import org.saturnclient.common.module.PlayerModule;
import org.saturnclient.ui.RenderScope;
import org.saturnclient.feature.Feature;
import org.saturnclient.feature.FeatureDetails;
import org.saturnclient.feature.FeatureLayout;
import org.saturnclient.feature.HudFeature;
/**
* KeystrokesFeature renders the WASD / mouse / space key states as an
* on-screen overlay.
*/
public class KeystrokesFeature extends Feature implements HudFeature {
// ---------------------------------------------------------------
// Configuration
// ---------------------------------------------------------------
private static final BoolProperty enabled = Property.bool(false);
private static final BoolProperty showMouse = Property.bool(true);
private static final BoolProperty showSpace = Property.bool(false);
private static final ColorProperty clickBg = Property.color(0xFFCCCCCC);
private static final ColorProperty clickFg = Property.color(0xFFFFFFFF);
private static final FeatureLayout layout = new FeatureLayout(78, 54);
// ---------------------------------------------------------------
// Layout constants
// ---------------------------------------------------------------
private static final int KEY_SIZE = 24;
private static final int KEY_SPACING = 3;
private static final int MOUSE_WIDTH = 38;
private static final int MOUSE_H = 24;
private static final int SPACE_H = 19;
// ---------------------------------------------------------------
// Cached key states (updated in tick)
// ---------------------------------------------------------------
private boolean w, a, s, d, lmb, rmb, space;
public KeystrokesFeature() {
super(
new FeatureDetails("Keystrokes", "keystrokes")
.description("Displays movement keystrokes")
.version("v0.2.0")
.tags("Utility"),
enabled.named("Enabled"),
showMouse.named("Show mouse clicks"),
showSpace.named("Show space"),
layout.prop(),
clickFg.named("Clicked fg"),
clickBg.named("Clicked bg"));
layout.renderBackground = false;
}
// ---------------------------------------------------------------
// Feature contract
// ---------------------------------------------------------------
@Override
public void tick() {
PlayerModule player = Providers.module.player();
w = player.isForwardPressed();
a = player.isLeftPressed();
s = player.isBackPressed();
d = player.isRightPressed();
lmb = player.isAttackPressed();
rmb = player.isUsePressed();
space = player.isJumpPressed();
refreshHeight();
}
@Override
public void renderHud(RenderScope scope) {
render(scope, true);
}
@Override
public void renderDummy(RenderScope scope) {
render(scope, false);
}
@Override
public FeatureLayout getDimensions() {
return layout;
}
@Override
public boolean isEnabled() {
return enabled.value;
}
@Override
public void onEnabled(boolean e) {
enabled.value = e;
}
// ---------------------------------------------------------------
// Rendering
// ---------------------------------------------------------------
private void render(RenderScope scope, boolean live) {
int yOffset = 0;
// W (top centre)
renderKey(scope, live && w, 'W', KEY_SIZE + KEY_SPACING, yOffset);
yOffset += KEY_SIZE + KEY_SPACING;
// A S D
renderKey(scope, live && a, 'A', 0, yOffset);
renderKey(scope, live && s, 'S', KEY_SIZE + KEY_SPACING, yOffset);
renderKey(scope, live && d, 'D', (KEY_SIZE + KEY_SPACING) * 2, yOffset);
yOffset += KEY_SIZE + KEY_SPACING;
// Spacebar (optional)
if (showSpace.value) {
renderSpaceKey(scope, live && space, 0, yOffset);
yOffset += SPACE_H + KEY_SPACING;
}
// Mouse buttons (optional)
if (showMouse.value) {
renderMouseKey(scope, live && lmb, "LMB", 0, yOffset);
renderMouseKey(scope, live && rmb, "RMB", MOUSE_WIDTH + KEY_SPACING, yOffset);
}
}
private void renderKey(RenderScope scope, boolean pressed, char c, int x, int y) {
int bg = pressed ? clickBg.value : layout.bgColor.value;
int fg = pressed ? clickFg.value : layout.fgColor.value;
scope.drawRoundedRectangle(x, y, KEY_SIZE, KEY_SIZE, layout.radius.value, bg);
scope.drawText(0.6f, String.valueOf(c), x + 9, y + 7, layout.font.value, fg);
}
private void renderMouseKey(RenderScope scope, boolean pressed, String label, int x, int y) {
int bg = pressed ? clickBg.value : layout.bgColor.value;
int fg = pressed ? clickFg.value : layout.fgColor.value;
scope.drawRoundedRectangle(x, y, MOUSE_WIDTH, MOUSE_H, layout.radius.value, bg);
scope.drawText(0.6f, label, x + 9, y + 7, layout.font.value, fg);
}
private void renderSpaceKey(RenderScope scope, boolean pressed, int x, int y) {
int bg = pressed ? clickBg.value : layout.bgColor.value;
int fg = pressed ? clickFg.value : layout.fgColor.value;
scope.drawRoundedRectangle(x, y, layout.width, SPACE_H, layout.radius.value, bg);
int lineY = y + SPACE_H / 2;
scope.drawRect(x + (layout.width - 30) / 2, lineY, 30, 1, fg);
}
private void refreshHeight() {
int h = KEY_SIZE * 2 + KEY_SPACING;
if (showSpace.value)
h += SPACE_H + KEY_SPACING;
if (showMouse.value)
h += MOUSE_H + KEY_SPACING;
layout.height = h;
}
}