mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 20:07:32 +00:00
287 lines
8.5 KiB
Java
287 lines
8.5 KiB
Java
package noppes.npcs.client.key;
|
|
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.settings.GameSettings;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import org.lwjgl.input.Keyboard;
|
|
import org.lwjgl.input.Mouse;
|
|
|
|
import java.util.function.Consumer;
|
|
|
|
public class KeyPreset {
|
|
/**
|
|
* @field SINGLE_PRESS => on releasing before 5 ticks press time
|
|
* @field PRESS_RELEASE => on pressing and releasing
|
|
*/
|
|
/** Press types for key events. */
|
|
public enum PressType { PRESS, HOLD, RELEASE, SINGLE_PRESS, PRESS_RELEASE }
|
|
|
|
public KeyState defaultState = new KeyState();
|
|
public KeyState currentState = new KeyState();
|
|
|
|
public String name, description;
|
|
public boolean shouldConflict = true;
|
|
public Consumer<KeyEvent> task;
|
|
|
|
// Throttling for hold-down behavior
|
|
private long lastActionTime = 0;
|
|
private long throttleInterval = 25;
|
|
private long firstThrottleInterval = 500;
|
|
private boolean isFirstAction = true;
|
|
|
|
private long pressStartMs = 0;
|
|
public boolean isDown;
|
|
|
|
|
|
public KeyPreset(String name) {
|
|
this.name = name;
|
|
}
|
|
|
|
public KeyPreset setDefaultState(int keyCode, boolean hasCtrl, boolean hasAlt, boolean hasShift) {
|
|
defaultState.setState(keyCode, hasCtrl, hasAlt, hasShift);
|
|
currentState.setState(keyCode, hasCtrl, hasAlt, hasShift);
|
|
return this;
|
|
}
|
|
|
|
public KeyPreset setDescription(String description) {
|
|
this.description = description;
|
|
return this;
|
|
}
|
|
|
|
public KeyPreset setTask(Consumer<KeyEvent> task) {
|
|
this.task = task;
|
|
return this;
|
|
}
|
|
|
|
public KeyPreset shouldConflict(boolean shouldConflict) {
|
|
this.shouldConflict = shouldConflict;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Fire every X ms when holding
|
|
*/
|
|
public KeyPreset setThrottleInterval(long ms) {
|
|
this.throttleInterval = ms;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set throttle interval for the first action (initial press)
|
|
*/
|
|
public KeyPreset setFirstThrottleInterval(long ms) {
|
|
this.firstThrottleInterval = ms;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Determine whether the given press type should be throttled. Only HOLD events are throttled.
|
|
*/
|
|
public boolean shouldThrottle(PressType pressType) {
|
|
if (throttleInterval <= 0) return false;
|
|
long currentTime = System.currentTimeMillis();
|
|
long intervalToUse = pressType == PressType.HOLD && isFirstAction && firstThrottleInterval > 0 ?
|
|
firstThrottleInterval : throttleInterval;
|
|
if (currentTime - lastActionTime < intervalToUse) return true;
|
|
lastActionTime = currentTime;
|
|
isFirstAction = false;
|
|
return false;
|
|
}
|
|
|
|
public void tick() {
|
|
int keyCode = keyCode();
|
|
if (keyCode == -1 || keyCode == 0)
|
|
return;
|
|
|
|
boolean isDown = isMouseKey() ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode);
|
|
isDown = isDown && (isCtrlKeyDown() == hasCtrl()) && (isAltKeyDown() == hasAlt()) && (isShiftKeyDown() == hasShift());
|
|
setDown(isDown);
|
|
}
|
|
|
|
private static final long SHORT_PRESS_MS = 250L;
|
|
|
|
public void setDown(boolean down) {
|
|
if (down && !isDown) { // just pressed
|
|
pressStartMs = System.currentTimeMillis();
|
|
onAction(PressType.PRESS, PressType.PRESS_RELEASE);
|
|
isFirstAction = true; // Reset for new press sequence
|
|
}
|
|
|
|
if (!down && isDown) { // just released
|
|
if (getPressTime() <= SHORT_PRESS_MS)
|
|
onAction(PressType.SINGLE_PRESS);
|
|
onAction(PressType.RELEASE, PressType.PRESS_RELEASE);
|
|
pressStartMs = 0;
|
|
}
|
|
|
|
if (down) // while held
|
|
onAction(PressType.HOLD);
|
|
|
|
this.isDown = down;
|
|
}
|
|
|
|
public long getPressTime() {
|
|
return pressStartMs > 0 ? (System.currentTimeMillis() - pressStartMs) : 0L;
|
|
}
|
|
|
|
public KeyPreset onAction(PressType... pressTypes) {
|
|
if (task == null)
|
|
return this;
|
|
|
|
for (PressType pressType : pressTypes)
|
|
if (!shouldThrottle(pressType))
|
|
this.task.accept(new KeyEvent(pressType, this));
|
|
|
|
return this;
|
|
}
|
|
|
|
public boolean isDefault() {
|
|
return currentState.equals(defaultState);
|
|
}
|
|
|
|
public boolean isMouseKey() {
|
|
return keyCode() < -1;
|
|
}
|
|
|
|
public int keyCode() {
|
|
return currentState.keyCode;
|
|
}
|
|
|
|
public boolean hasCtrl() {
|
|
return currentState.hasCtrl;
|
|
}
|
|
|
|
public boolean hasAlt() {
|
|
return currentState.hasAlt;
|
|
}
|
|
|
|
public boolean hasShift() {
|
|
return currentState.hasShift;
|
|
}
|
|
|
|
public String getKeyName() {
|
|
return currentState.getName();
|
|
}
|
|
|
|
public void clear() {
|
|
currentState.clear();
|
|
}
|
|
|
|
public void writeToNbt(NBTTagCompound c) {
|
|
c.setTag(name, currentState.writeToNbt());
|
|
}
|
|
|
|
public void readFromNbt(NBTTagCompound compound) {
|
|
currentState.readFromNbt(compound.getCompoundTag(name));
|
|
}
|
|
|
|
public boolean equals(Object preset) {
|
|
if (preset == this)
|
|
return true;
|
|
|
|
if (preset instanceof KeyPreset) {
|
|
KeyPreset key = (KeyPreset) preset;
|
|
return key.currentState.equals(currentState);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static class KeyState {
|
|
public int keyCode = -1;
|
|
public boolean hasCtrl, hasAlt, hasShift;
|
|
|
|
public void setState(int keyCode, boolean hasCtrl, boolean hasAlt, boolean hasShift) {
|
|
this.keyCode = keyCode;
|
|
this.hasCtrl = hasCtrl;
|
|
this.hasAlt = hasAlt;
|
|
this.hasShift = hasShift;
|
|
}
|
|
|
|
public void readFrom(KeyState state) {
|
|
keyCode = state.keyCode;
|
|
hasCtrl = state.hasCtrl;
|
|
hasShift = state.hasShift;
|
|
hasAlt = state.hasAlt;
|
|
}
|
|
|
|
public void writeTo(KeyState state) {
|
|
state.setState(keyCode, hasCtrl, hasAlt, hasShift);
|
|
}
|
|
|
|
public boolean hasState() {
|
|
return keyCode != -1;
|
|
}
|
|
|
|
public void clear() {
|
|
this.keyCode = -1;
|
|
hasCtrl = hasAlt = hasShift = false;
|
|
}
|
|
|
|
public boolean equals(Object preset) {
|
|
if (preset == this)
|
|
return true;
|
|
|
|
if (preset instanceof KeyState) {
|
|
KeyState state = (KeyState) preset;
|
|
return state.keyCode == keyCode && state.hasCtrl == hasCtrl && state.hasAlt == hasAlt && state.hasShift == hasShift;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public NBTTagCompound writeToNbt() {
|
|
NBTTagCompound compound = new NBTTagCompound();
|
|
compound.setInteger("keyCode", keyCode);
|
|
compound.setBoolean("hasCtrl", hasCtrl);
|
|
compound.setBoolean("hasShift", hasShift);
|
|
compound.setBoolean("hasAlt", hasAlt);
|
|
return compound;
|
|
}
|
|
|
|
public void readFromNbt(NBTTagCompound compound) {
|
|
this.keyCode = compound.getInteger("keyCode");
|
|
this.hasCtrl = compound.getBoolean("hasCtrl");
|
|
this.hasShift = compound.getBoolean("hasShift");
|
|
this.hasAlt = compound.getBoolean("hasAlt");
|
|
}
|
|
|
|
public String getName() {
|
|
int code = keyCode;
|
|
String name = "";
|
|
|
|
if (code == LEFT_MOUSE)
|
|
name = "Left Mouse";
|
|
else if (code == RIGHT_MOUSE)
|
|
name = "Right Mouse";
|
|
else if (code == MIDDLE_MOUSE)
|
|
name = "Middle Mouse";
|
|
else {
|
|
name = code == -1 ? "" : GameSettings.getKeyDisplayString(code);
|
|
if (name.contains("Button"))
|
|
name = name.replace("Button", "Mouse");
|
|
}
|
|
|
|
return (hasCtrl ? "CTRL " : "") + (hasAlt ? "ALT " : "") + (hasShift ? "SHIFT " : "") + name;
|
|
}
|
|
}
|
|
|
|
public static final int LEFT_MOUSE = -100, RIGHT_MOUSE = -99, MIDDLE_MOUSE = -98, MOUSE_4 = -97, MOUSE_5 = -96;
|
|
|
|
public static boolean isCtrlKeyDown() {
|
|
return Minecraft.isRunningOnMac ? Keyboard.isKeyDown(219) || Keyboard.isKeyDown(220) : Keyboard.isKeyDown(29) || Keyboard.isKeyDown(157);
|
|
}
|
|
|
|
public static boolean isAltKeyDown() {
|
|
return Keyboard.isKeyDown(56) || Keyboard.isKeyDown(184);
|
|
}
|
|
|
|
public static boolean isShiftKeyDown() {
|
|
return Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54);
|
|
}
|
|
|
|
public static boolean isNotCtrlAltShift(int key) {
|
|
return key != 219 && key != 220 && key != 29 && key != 157 && key != 42 && key != 54 && key != 56 && key != 184;
|
|
}
|
|
}
|