mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-13 21:54:08 +00:00
Merge branch 'dev' into syntax-highlighter-unified
This commit is contained in:
commit
86541779db
13 files changed
+292
-155
No files matched your search
+3
-3
@@ -14,7 +14,7 @@ public class AbilityPotionEffect {
|
||||
private EnumPotionType type = EnumPotionType.None;
|
||||
private int manualPotionId = 0;
|
||||
private int durationTicks = 60;
|
||||
private int amplifier = 0; // 0-10
|
||||
private int amplifier = 0; // 0-255 (Manual), 0-10 (preset)
|
||||
|
||||
public AbilityPotionEffect() {
|
||||
}
|
||||
@@ -22,7 +22,7 @@ public class AbilityPotionEffect {
|
||||
public AbilityPotionEffect(EnumPotionType type, int durationTicks, int amplifier) {
|
||||
this.type = type;
|
||||
this.durationTicks = Math.max(1, durationTicks);
|
||||
this.amplifier = Math.max(0, Math.min(10, amplifier));
|
||||
this.amplifier = Math.max(0, Math.min(255, amplifier));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,7 +120,7 @@ public class AbilityPotionEffect {
|
||||
}
|
||||
|
||||
public void setAmplifier(int amplifier) {
|
||||
this.amplifier = Math.max(0, Math.min(10, amplifier));
|
||||
this.amplifier = Math.max(0, Math.min(255, amplifier));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -112,11 +112,22 @@ public class AbilityFieldBuilder extends GuiFieldBuilder {
|
||||
widgetId++;
|
||||
|
||||
if (effect.getType() != EnumPotionType.Fire) {
|
||||
GuiNpcButton ampBtn = new GuiNpcButton(widgetId, colLLabel + 158, y, 40, 20, ampValues, effect.getAmplifier());
|
||||
sw.addButton(ampBtn);
|
||||
buttonFieldMap.put(widgetId, def);
|
||||
effectWidgetMeta.put(widgetId, new int[]{e, 2});
|
||||
widgetId++;
|
||||
if (effect.getType() == EnumPotionType.Manual) {
|
||||
GuiNpcTextField ampField = new GuiNpcTextField(widgetId, parent, fontRenderer,
|
||||
colLLabel + 158, y, 40, 20, String.valueOf(effect.getAmplifier()));
|
||||
ampField.setIntegersOnly();
|
||||
ampField.setMinMaxDefault(0, 255, 0);
|
||||
sw.addTextField(ampField);
|
||||
textFieldMap.put(widgetId, def);
|
||||
effectWidgetMeta.put(widgetId, new int[]{e, 2});
|
||||
widgetId++;
|
||||
} else {
|
||||
GuiNpcButton ampBtn = new GuiNpcButton(widgetId, colLLabel + 158, y, 40, 20, ampValues, effect.getAmplifier());
|
||||
sw.addButton(ampBtn);
|
||||
buttonFieldMap.put(widgetId, def);
|
||||
effectWidgetMeta.put(widgetId, new int[]{e, 2});
|
||||
widgetId++;
|
||||
}
|
||||
} else {
|
||||
widgetId++;
|
||||
}
|
||||
@@ -367,8 +378,14 @@ public class AbilityFieldBuilder extends GuiFieldBuilder {
|
||||
if (effects == null) return false;
|
||||
switch (action) {
|
||||
case 0:
|
||||
if (idx < effects.size())
|
||||
effects.get(idx).setType(EnumPotionType.fromIndexNoNone(((GuiNpcButton) button).getValue()));
|
||||
if (idx < effects.size()) {
|
||||
EnumPotionType oldType = effects.get(idx).getType();
|
||||
EnumPotionType newType = EnumPotionType.fromIndexNoNone(((GuiNpcButton) button).getValue());
|
||||
if (oldType == EnumPotionType.Manual && newType != EnumPotionType.Manual) {
|
||||
effects.get(idx).setAmplifier(0);
|
||||
}
|
||||
effects.get(idx).setType(newType);
|
||||
}
|
||||
return true;
|
||||
case 2:
|
||||
if (idx < effects.size())
|
||||
@@ -471,6 +488,7 @@ public class AbilityFieldBuilder extends GuiFieldBuilder {
|
||||
List<AbilityPotionEffect> effects = (List<AbilityPotionEffect>) def.getValue();
|
||||
if (effects != null && idx < effects.size()) {
|
||||
if (action == 1) effects.get(idx).setDurationTicks(field.getInteger());
|
||||
else if (action == 2) effects.get(idx).setAmplifier(field.getInteger());
|
||||
else if (action == 5) effects.get(idx).setManualPotionId(field.getInteger());
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -14,11 +14,12 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import noppes.npcs.client.ClientProxy;
|
||||
import noppes.npcs.client.KeyPressHandler;
|
||||
import noppes.npcs.client.gui.player.GuiAuctionInterface;
|
||||
import noppes.npcs.controllers.MagicController;
|
||||
import noppes.npcs.controllers.data.Magic;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -236,7 +237,7 @@ public class AttributeItemUtil {
|
||||
// Get the RPGCore compound and then the Attributes compound.
|
||||
NBTTagCompound rpgCore = compound.hasKey(TAG_RPGCORE) ? compound.getCompoundTag(TAG_RPGCORE) : new NBTTagCompound();
|
||||
NBTTagCompound attrTag = rpgCore.hasKey(TAG_ATTRIBUTES) ? rpgCore.getCompoundTag(TAG_ATTRIBUTES) : new NBTTagCompound();
|
||||
if (Keyboard.isKeyDown(ClientProxy.NPCButton.getKeyCode()) || override) {
|
||||
if (KeyPressHandler.isKeyBindDown(ClientProxy.NPCButton) || override) {
|
||||
List<String> newTooltips = new ArrayList<>();
|
||||
if (!tooltip.isEmpty() && !override) {
|
||||
newTooltips.add(tooltip.get(0));
|
||||
@@ -332,7 +333,7 @@ public class AttributeItemUtil {
|
||||
tooltip = newTooltips;
|
||||
}
|
||||
} else {
|
||||
String keyName = Keyboard.getKeyName(ClientProxy.NPCButton.getKeyCode());
|
||||
String keyName = GameSettings.getKeyDisplayString(ClientProxy.NPCButton.getKeyCode());
|
||||
tooltip.add(EnumChatFormatting.YELLOW + "" + EnumChatFormatting.ITALIC +
|
||||
StatCollector.translateToLocal("rpgcore:tooltip").replace("%key%", keyName));
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Mod(modid = "customnpcs", name = "CustomNPC+", version = "1.11-beta8.1")
|
||||
@Mod(modid = "customnpcs", name = "CustomNPC+", version = "1.11-beta9")
|
||||
public class CustomNpcs {
|
||||
|
||||
@SidedProxy(clientSide = "noppes.npcs.client.ClientProxy", serverSide = "noppes.npcs.CommonProxy")
|
||||
|
||||
@@ -27,6 +27,7 @@ import noppes.npcs.client.gui.hud.EnumHudComponent;
|
||||
import noppes.npcs.client.gui.hud.QuestTrackingComponent;
|
||||
import noppes.npcs.client.gui.hud.ability.AbilityHotbarComponent;
|
||||
import noppes.npcs.client.gui.player.AuctionTooltipHandler;
|
||||
import noppes.npcs.client.KeyPressHandler;
|
||||
import noppes.npcs.client.renderer.MarkRenderer;
|
||||
import noppes.npcs.client.renderer.RenderCNPCPlayer;
|
||||
import noppes.npcs.constants.EnumAnimationPart;
|
||||
@@ -85,6 +86,14 @@ public class ClientEventHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
public void onMouse(MouseEvent event) {
|
||||
// Always track mouse button state for KeyPressHandler FIRST.
|
||||
// Canceled MouseEvents skip FML's MouseInputEvent entirely
|
||||
// (Minecraft.java: if postMouseEvent() continue), so this is the
|
||||
// only reliable place to capture mouse button press/release.
|
||||
if (event.button >= 0) {
|
||||
KeyPressHandler.trackMouseButton(event.button, event.buttonstate);
|
||||
}
|
||||
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
if (mc.currentScreen != null)
|
||||
return;
|
||||
@@ -100,30 +109,17 @@ public class ClientEventHandler {
|
||||
}
|
||||
|
||||
// Ability Hotbar: Hold HUD key + scroll wheel to cycle
|
||||
if (event.dwheel != 0 && ClientProxy.AbilityHudKey != null) {
|
||||
int hudKeyCode = ClientProxy.AbilityHudKey.getKeyCode();
|
||||
boolean hudKeyHeld = false;
|
||||
if (hudKeyCode > 0) {
|
||||
hudKeyHeld = hudKeyCode < org.lwjgl.input.Keyboard.getKeyCount()
|
||||
&& org.lwjgl.input.Keyboard.isKeyDown(hudKeyCode);
|
||||
} else if (hudKeyCode < 0) {
|
||||
int mouseButton = hudKeyCode + 100;
|
||||
hudKeyHeld = mouseButton >= 0
|
||||
&& mouseButton < org.lwjgl.input.Mouse.getButtonCount()
|
||||
&& org.lwjgl.input.Mouse.isButtonDown(mouseButton);
|
||||
}
|
||||
if (hudKeyHeld) {
|
||||
AbilityHotbarComponent comp = (AbilityHotbarComponent) ClientHudManager.getInstance()
|
||||
.getHudComponents().get(EnumHudComponent.AbilityHotbar);
|
||||
if (comp != null && comp.hasAnyAbilities()) {
|
||||
if (event.dwheel > 0) {
|
||||
comp.onCyclePrev();
|
||||
} else {
|
||||
comp.onCycleNext();
|
||||
}
|
||||
event.setCanceled(true);
|
||||
return;
|
||||
if (event.dwheel != 0 && KeyPressHandler.isHudKeyHeld()) {
|
||||
AbilityHotbarComponent comp = (AbilityHotbarComponent) ClientHudManager.getInstance()
|
||||
.getHudComponents().get(EnumHudComponent.AbilityHotbar);
|
||||
if (comp != null && comp.hasAnyAbilities()) {
|
||||
if (event.dwheel > 0) {
|
||||
comp.onCyclePrev();
|
||||
} else {
|
||||
comp.onCycleNext();
|
||||
}
|
||||
event.setCanceled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -296,6 +296,7 @@ public class ClientProxy extends CommonProxy {
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityNPCGolem.class, new RenderNPCHumanMale(
|
||||
new ModelNPCGolem(0), new ModelNPCGolem(1F), new ModelNPCGolem(0.5F)));
|
||||
FMLCommonHandler.instance().bus().register(new ClientTickHandler());
|
||||
FMLCommonHandler.instance().bus().register(new KeyPressHandler());
|
||||
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(TileBlockAnvil.class, new BlockCarpentryBenchRenderer());
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(TileMailbox.class, new BlockMailboxRenderer());
|
||||
|
||||
@@ -2,7 +2,6 @@ package noppes.npcs.client;
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.EventPriority;
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import cpw.mods.fml.common.gameevent.InputEvent;
|
||||
import cpw.mods.fml.common.gameevent.TickEvent;
|
||||
import cpw.mods.fml.common.gameevent.TickEvent.Phase;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
@@ -12,33 +11,26 @@ import kamkeel.npcs.controllers.data.telegraph.TelegraphManager;
|
||||
import kamkeel.npcs.network.PacketClient;
|
||||
import kamkeel.npcs.network.packets.data.RequestProperSpawnData;
|
||||
import kamkeel.npcs.network.packets.player.CheckPlayerValue;
|
||||
import kamkeel.npcs.network.packets.player.InputDevicePacket;
|
||||
import kamkeel.npcs.network.packets.player.ScreenSizePacket;
|
||||
import kamkeel.npcs.network.packets.player.SpecialKeyStatePacket;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.ContainerPlayer;
|
||||
import net.minecraft.world.World;
|
||||
import noppes.npcs.CustomNpcs;
|
||||
import noppes.npcs.client.controllers.MusicController;
|
||||
import noppes.npcs.client.controllers.ScriptSoundController;
|
||||
import noppes.npcs.client.gui.hud.ClientHudManager;
|
||||
import noppes.npcs.client.gui.hud.CompassHudComponent;
|
||||
import noppes.npcs.client.gui.hud.EnumHudComponent;
|
||||
import noppes.npcs.client.gui.hud.HudComponent;
|
||||
import noppes.npcs.client.gui.player.inventory.GuiCNPCInventory;
|
||||
import noppes.npcs.client.renderer.RenderNPCInterface;
|
||||
import noppes.npcs.constants.EnumRoleType;
|
||||
import noppes.npcs.constants.MarkType;
|
||||
import noppes.npcs.CustomNpcs;
|
||||
import noppes.npcs.controllers.data.MarkData;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
import noppes.npcs.entity.EntityNPCInterface;
|
||||
import noppes.npcs.roles.RoleMount;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
import tconstruct.client.tabs.InventoryTabCustomNpc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -49,10 +41,6 @@ public class ClientTickHandler {
|
||||
private int prevWidth = 0;
|
||||
private int prevHeight = 0;
|
||||
private boolean otherContainer = false;
|
||||
private int buttonPressed = -1;
|
||||
private long buttonTime = 0L;
|
||||
private final int[] ignoreKeys = new int[]{157, 29, 54, 42, 184, 56, 220, 219};
|
||||
private boolean lastSpecialKeyDown = false;
|
||||
private boolean wasMovementSuppressed = false;
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
@@ -72,18 +60,6 @@ public class ClientTickHandler {
|
||||
if (event.phase == Phase.START) {
|
||||
EntityPlayer player = mc.thePlayer;
|
||||
if (player != null) {
|
||||
// Only process special key when no GUI screen is open
|
||||
boolean specialKeyDown = mc.currentScreen == null
|
||||
&& ClientProxy.SpecialKey != null && Keyboard.isKeyDown(ClientProxy.SpecialKey.getKeyCode());
|
||||
if (specialKeyDown != lastSpecialKeyDown) {
|
||||
PlayerData data = CustomNpcs.proxy.getPlayerData(player);
|
||||
if (data != null) {
|
||||
data.setSpecialKeyDown(specialKeyDown);
|
||||
}
|
||||
SpecialKeyStatePacket.send(specialKeyDown);
|
||||
lastSpecialKeyDown = specialKeyDown;
|
||||
}
|
||||
|
||||
boolean suppressMovement = mc.currentScreen == null && ClientAbilityState.shouldSuppressMovementInput();
|
||||
if (!suppressMovement && wasMovementSuppressed) {
|
||||
syncMovementKeyStates(mc);
|
||||
@@ -257,56 +233,6 @@ public class ClientTickHandler {
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onMouse(InputEvent.MouseInputEvent event) {
|
||||
if (Mouse.getEventButton() == -1 && Mouse.getEventDWheel() == 0)
|
||||
return;
|
||||
|
||||
InputDevicePacket.sendMouse(Mouse.getEventButton(), Mouse.getEventDWheel(), Mouse.isButtonDown(Mouse.getEventButton()));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onKey(InputEvent.KeyInputEvent event) {
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
if (ClientProxy.NPCButton.isPressed()) {
|
||||
if (mc.currentScreen == null) {
|
||||
InventoryTabCustomNpc.tabHelper();
|
||||
} else if (mc.currentScreen instanceof GuiCNPCInventory)
|
||||
mc.setIngameFocus();
|
||||
}
|
||||
|
||||
if (!Keyboard.isRepeatEvent()) {
|
||||
int key = Keyboard.getEventKey();
|
||||
boolean keyDown = Keyboard.isKeyDown(key);
|
||||
|
||||
// Block movement keys during ability lock (only when no GUI is open and world exists).
|
||||
// Non-movement keys (ESC, chat, inventory, etc.) always pass through.
|
||||
if (mc.theWorld != null && mc.currentScreen == null && keyDown
|
||||
&& ClientAbilityState.shouldSuppressMovementInput() && isMovementKey(key)) {
|
||||
// Unpress the keybind so vanilla doesn't process it
|
||||
KeyBinding.setKeyBindState(key, false);
|
||||
return;
|
||||
}
|
||||
|
||||
InputDevicePacket.sendKeyboard(key, keyDown);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a key code corresponds to a movement keybind (WASD, jump, sneak, sprint).
|
||||
*/
|
||||
private boolean isMovementKey(int keyCode) {
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
return keyCode == mc.gameSettings.keyBindForward.getKeyCode()
|
||||
|| keyCode == mc.gameSettings.keyBindBack.getKeyCode()
|
||||
|| keyCode == mc.gameSettings.keyBindLeft.getKeyCode()
|
||||
|| keyCode == mc.gameSettings.keyBindRight.getKeyCode()
|
||||
|| keyCode == mc.gameSettings.keyBindJump.getKeyCode()
|
||||
|| keyCode == mc.gameSettings.keyBindSneak.getKeyCode()
|
||||
|| keyCode == mc.gameSettings.keyBindSprint.getKeyCode();
|
||||
}
|
||||
|
||||
private void syncMovementKeyStates(Minecraft mc) {
|
||||
syncKeyBindingState(mc.gameSettings.keyBindForward);
|
||||
syncKeyBindingState(mc.gameSettings.keyBindBack);
|
||||
@@ -318,28 +244,7 @@ public class ClientTickHandler {
|
||||
}
|
||||
|
||||
private void syncKeyBindingState(KeyBinding keyBinding) {
|
||||
int keyCode = keyBinding.getKeyCode();
|
||||
boolean pressed;
|
||||
if (keyCode < 0) {
|
||||
pressed = Mouse.isButtonDown(keyCode + 100);
|
||||
} else {
|
||||
pressed = Keyboard.isKeyDown(keyCode);
|
||||
}
|
||||
KeyBinding.setKeyBindState(keyCode, pressed);
|
||||
}
|
||||
|
||||
private boolean isIgnoredKey(int key) {
|
||||
int[] var2 = this.ignoreKeys;
|
||||
int var3 = var2.length;
|
||||
|
||||
for (int var4 = 0; var4 < var3; ++var4) {
|
||||
int i = var2[var4];
|
||||
if (i == key) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
KeyBinding.setKeyBindState(keyBinding.getKeyCode(), KeyPressHandler.isKeyBindDown(keyBinding));
|
||||
}
|
||||
|
||||
private final int SCAN_RANGE = 128;
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
package noppes.npcs.client;
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import cpw.mods.fml.common.gameevent.InputEvent;
|
||||
import cpw.mods.fml.common.gameevent.TickEvent;
|
||||
import kamkeel.npcs.network.packets.player.InputDevicePacket;
|
||||
import kamkeel.npcs.network.packets.player.SpecialKeyStatePacket;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import noppes.npcs.CustomNpcs;
|
||||
import noppes.npcs.client.gui.player.inventory.GuiCNPCInventory;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
import tconstruct.client.tabs.InventoryTabCustomNpc;
|
||||
|
||||
/**
|
||||
* Centralized input handler for CustomNPC+ keybindings.
|
||||
* Handles both keyboard and mouse input events so keybinds work
|
||||
* regardless of whether they're bound to a key or mouse button.
|
||||
* <p>
|
||||
* All keybind state queries (pressed, held, released) should go through
|
||||
* this class to avoid crashes with mouse-bound keys.
|
||||
* <p>
|
||||
* Mouse button states are tracked from MouseEvent (Forge bus) via
|
||||
* {@link #trackMouseButton}, because canceled MouseEvents cause Minecraft
|
||||
* to skip FML's MouseInputEvent entirely. This is the only reliable source.
|
||||
*/
|
||||
public class KeyPressHandler {
|
||||
|
||||
// ── Mouse Button Tracking ────────────────────────────────────────────
|
||||
// Tracked from MouseEvent (Forge bus, via ClientEventHandler.onMouse)
|
||||
// which fires BEFORE cancellation can skip MouseInputEvent.
|
||||
private static final boolean[] mouseButtonsDown = new boolean[16];
|
||||
|
||||
// ── Tracked Held States ──────────────────────────────────────────────
|
||||
private static boolean specialKeyHeld = false;
|
||||
private static boolean hudKeyHeld = false;
|
||||
|
||||
// ── Event Handlers ──────────────────────────────────────────────────
|
||||
|
||||
@SubscribeEvent
|
||||
public void onKeyPress(InputEvent.KeyInputEvent event) {
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
updateHeldStates(mc);
|
||||
handleNPCButton(mc);
|
||||
|
||||
if (!Keyboard.isRepeatEvent()) {
|
||||
int key = Keyboard.getEventKey();
|
||||
boolean keyDown = Keyboard.isKeyDown(key);
|
||||
|
||||
// Block movement keys during ability lock (only when no GUI is open).
|
||||
if (mc.theWorld != null && mc.currentScreen == null && keyDown
|
||||
&& ClientAbilityState.shouldSuppressMovementInput() && isMovementKey(key)) {
|
||||
KeyBinding.setKeyBindState(key, false);
|
||||
return;
|
||||
}
|
||||
|
||||
InputDevicePacket.sendKeyboard(key, keyDown);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onMousePress(InputEvent.MouseInputEvent event) {
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
// Button state already tracked by trackMouseButton() from MouseEvent.
|
||||
// Just update held states and handle keybind actions.
|
||||
updateHeldStates(mc);
|
||||
handleNPCButton(mc);
|
||||
|
||||
int button = Mouse.getEventButton();
|
||||
if (button == -1 && Mouse.getEventDWheel() == 0)
|
||||
return;
|
||||
|
||||
InputDevicePacket.sendMouse(button, Mouse.getEventDWheel(),
|
||||
button >= 0 && Mouse.getEventButtonState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Per-tick safety net: sync tracked mouse button states with hardware
|
||||
* in case an event was missed (e.g. window focus loss).
|
||||
*/
|
||||
@SubscribeEvent
|
||||
public void onClientTick(TickEvent.ClientTickEvent event) {
|
||||
if (event.phase != TickEvent.Phase.START) return;
|
||||
|
||||
// Correct any stuck mouse buttons from missed release events
|
||||
for (int i = 0; i < mouseButtonsDown.length; i++) {
|
||||
if (mouseButtonsDown[i] && i < Mouse.getButtonCount() && !Mouse.isButtonDown(i)) {
|
||||
mouseButtonsDown[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
updateHeldStates(Minecraft.getMinecraft());
|
||||
}
|
||||
|
||||
// ── Mouse Button Tracking (called from Forge MouseEvent) ─────────────
|
||||
|
||||
/**
|
||||
* Called from {@code ClientEventHandler.onMouse(MouseEvent)} at the very
|
||||
* start, BEFORE any cancellation logic. This is the primary source of
|
||||
* mouse button state because canceled MouseEvents cause Minecraft to
|
||||
* skip {@code FMLCommonHandler.fireMouseInput()} entirely, so
|
||||
* MouseInputEvent never fires for those events.
|
||||
*/
|
||||
public static void trackMouseButton(int button, boolean down) {
|
||||
if (button >= 0 && button < mouseButtonsDown.length) {
|
||||
mouseButtonsDown[button] = down;
|
||||
}
|
||||
updateHeldStates(Minecraft.getMinecraft());
|
||||
}
|
||||
|
||||
// ── State Updates ────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Refresh all tracked held states.
|
||||
* Called on every input event and every tick.
|
||||
*/
|
||||
private static void updateHeldStates(Minecraft mc) {
|
||||
boolean noScreen = mc.currentScreen == null;
|
||||
|
||||
// ── SpecialKey (edge-detected, sends packet on change) ──
|
||||
boolean specialDown = noScreen && isKeyBindDown(ClientProxy.SpecialKey);
|
||||
if (specialDown != specialKeyHeld) {
|
||||
specialKeyHeld = specialDown;
|
||||
if (mc.thePlayer != null) {
|
||||
PlayerData data = CustomNpcs.proxy.getPlayerData(mc.thePlayer);
|
||||
if (data != null) {
|
||||
data.setSpecialKeyDown(specialDown);
|
||||
}
|
||||
SpecialKeyStatePacket.send(specialDown);
|
||||
}
|
||||
}
|
||||
|
||||
// ── AbilityHudKey ──
|
||||
hudKeyHeld = noScreen && isKeyBindDown(ClientProxy.AbilityHudKey);
|
||||
}
|
||||
|
||||
// ── Keybind Actions ─────────────────────────────────────────────────
|
||||
|
||||
private static void handleNPCButton(Minecraft mc) {
|
||||
if (ClientProxy.NPCButton == null) return;
|
||||
if (ClientProxy.NPCButton.isPressed()) {
|
||||
if (mc.currentScreen == null) {
|
||||
InventoryTabCustomNpc.tabHelper();
|
||||
} else if (mc.currentScreen instanceof GuiCNPCInventory) {
|
||||
mc.setIngameFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Public State Queries ─────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Whether the SpecialKey is currently held down.
|
||||
*/
|
||||
public static boolean isSpecialKeyHeld() {
|
||||
return specialKeyHeld;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the AbilityHudKey is currently held down.
|
||||
*/
|
||||
public static boolean isHudKeyHeld() {
|
||||
return hudKeyHeld;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a KeyBinding is currently held down.
|
||||
* Works for both keyboard keys (positive codes) and mouse buttons (negative codes).
|
||||
* <p>
|
||||
* Mouse buttons use event-tracked state (from MouseEvent via trackMouseButton)
|
||||
* so the result is accurate even when called during keyboard event processing.
|
||||
*/
|
||||
public static boolean isKeyBindDown(KeyBinding keyBinding) {
|
||||
if (keyBinding == null) return false;
|
||||
int keyCode = keyBinding.getKeyCode();
|
||||
if (keyCode == 0) return false;
|
||||
|
||||
if (keyCode < 0) {
|
||||
int mouseButton = keyCode + 100;
|
||||
return mouseButton >= 0 && mouseButton < mouseButtonsDown.length
|
||||
&& mouseButtonsDown[mouseButton];
|
||||
}
|
||||
|
||||
return keyCode < Keyboard.getKeyCount() && Keyboard.isKeyDown(keyCode);
|
||||
}
|
||||
|
||||
// ── Internal Helpers ────────────────────────────────────────────────
|
||||
|
||||
private static boolean isMovementKey(int keyCode) {
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
return keyCode == mc.gameSettings.keyBindForward.getKeyCode()
|
||||
|| keyCode == mc.gameSettings.keyBindBack.getKeyCode()
|
||||
|| keyCode == mc.gameSettings.keyBindLeft.getKeyCode()
|
||||
|| keyCode == mc.gameSettings.keyBindRight.getKeyCode()
|
||||
|| keyCode == mc.gameSettings.keyBindJump.getKeyCode()
|
||||
|| keyCode == mc.gameSettings.keyBindSneak.getKeyCode()
|
||||
|| keyCode == mc.gameSettings.keyBindSprint.getKeyCode();
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,13 @@ public class SubGuiNpcMeleeProperties extends SubGuiInterface implements ITextfi
|
||||
if (stats.potionType != EnumPotionType.Fire) {
|
||||
y += 30;
|
||||
addLabel(new GuiNpcLabel(7, "stats.amplify", guiLeft + 5, y + 5));
|
||||
addButton(new GuiButtonBiDirectional(7, guiLeft + 85, y, 52, 20, new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}, stats.potionAmp));
|
||||
if (stats.potionType == EnumPotionType.Manual) {
|
||||
addTextField(new GuiNpcTextField(7, this, fontRendererObj, guiLeft + 85, y, 52, 18, stats.potionAmp + ""));
|
||||
getTextField(7).integersOnly = true;
|
||||
getTextField(7).setMinMaxDefault(0, 255, 0);
|
||||
} else {
|
||||
addButton(new GuiButtonBiDirectional(7, guiLeft + 85, y, 52, 20, new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}, stats.potionAmp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +82,8 @@ public class SubGuiNpcMeleeProperties extends SubGuiInterface implements ITextfi
|
||||
stats.knockback = textfield.getInteger();
|
||||
} else if (textfield.id == 6) {
|
||||
stats.potionDuration = textfield.getInteger();
|
||||
} else if (textfield.id == 7) {
|
||||
stats.potionAmp = textfield.getInteger();
|
||||
} else if (textfield.id == 8) {
|
||||
stats.potionManualId = textfield.getInteger();
|
||||
}
|
||||
@@ -84,7 +92,11 @@ public class SubGuiNpcMeleeProperties extends SubGuiInterface implements ITextfi
|
||||
protected void actionPerformed(GuiButton guibutton) {
|
||||
GuiNpcButton button = (GuiNpcButton) guibutton;
|
||||
if (button.id == 5) {
|
||||
stats.potionType = EnumPotionType.fromOrdinal(button.getValue());
|
||||
EnumPotionType newType = EnumPotionType.fromOrdinal(button.getValue());
|
||||
if (stats.potionType == EnumPotionType.Manual && newType != EnumPotionType.Manual) {
|
||||
stats.potionAmp = 0;
|
||||
}
|
||||
stats.potionType = newType;
|
||||
initGui();
|
||||
}
|
||||
if (button.id == 7) {
|
||||
|
||||
@@ -97,7 +97,13 @@ public class SubGuiNpcProjectiles extends SubGuiInterface implements ITextfieldL
|
||||
} else {
|
||||
internalY += 30;
|
||||
addLabel(new GuiNpcLabel(70, "stats.amplify", guiLeft + 210, internalY + 5));
|
||||
addButton(new GuiButtonBiDirectional(10, guiLeft + 280, internalY, 52, 20, new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}, stats.pEffAmp));
|
||||
if (stats.pEffect == EnumPotionType.Manual) {
|
||||
addTextField(new GuiNpcTextField(10, this, fontRendererObj, guiLeft + 280, internalY, 52, 20, stats.pEffAmp + ""));
|
||||
getTextField(10).integersOnly = true;
|
||||
getTextField(10).setMinMaxDefault(0, 255, 0);
|
||||
} else {
|
||||
addButton(new GuiButtonBiDirectional(10, guiLeft + 280, internalY, 52, 20, new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}, stats.pEffAmp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +138,8 @@ public class SubGuiNpcProjectiles extends SubGuiInterface implements ITextfieldL
|
||||
stats.pSpeed = textfield.getInteger();
|
||||
} else if (textfield.id == 5) {
|
||||
stats.pDur = textfield.getInteger();
|
||||
} else if (textfield.id == 10) {
|
||||
stats.pEffAmp = textfield.getInteger();
|
||||
} else if (textfield.id == 11) {
|
||||
stats.pManualId = textfield.getInteger();
|
||||
}
|
||||
@@ -154,7 +162,11 @@ public class SubGuiNpcProjectiles extends SubGuiInterface implements ITextfieldL
|
||||
stats.pArea = button.getValue();
|
||||
}
|
||||
if (button.id == 4) {
|
||||
stats.pEffect = EnumPotionType.fromOrdinal(button.getValue());
|
||||
EnumPotionType newType = EnumPotionType.fromOrdinal(button.getValue());
|
||||
if (stats.pEffect == EnumPotionType.Manual && newType != EnumPotionType.Manual) {
|
||||
stats.pEffAmp = 0;
|
||||
}
|
||||
stats.pEffect = newType;
|
||||
initGui();
|
||||
}
|
||||
if (button.id == 5) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import kamkeel.npcs.network.packets.player.ability.AbilityHotbarSelectPacket;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import noppes.npcs.client.ClientProxy;
|
||||
import noppes.npcs.client.ClientAbilityState;
|
||||
import noppes.npcs.client.KeyPressHandler;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.ScaledResolution;
|
||||
@@ -602,22 +603,7 @@ public class AbilityHotbarComponent extends HudComponent {
|
||||
}
|
||||
|
||||
private boolean isHudKeyHeld() {
|
||||
if (ClientProxy.AbilityHudKey == null) return false;
|
||||
int keyCode = ClientProxy.AbilityHudKey.getKeyCode();
|
||||
if (keyCode == 0 || keyCode == -1) return false;
|
||||
|
||||
// Mouse bindings are encoded as negative key codes (offset by 100).
|
||||
if (keyCode < -1) {
|
||||
int mouseButton = keyCode + 100;
|
||||
return mouseButton >= 0
|
||||
&& mouseButton < org.lwjgl.input.Mouse.getButtonCount()
|
||||
&& org.lwjgl.input.Mouse.isButtonDown(mouseButton);
|
||||
}
|
||||
|
||||
// Guard against invalid/out-of-range keyboard codes to avoid Buffer.checkIndex crashes.
|
||||
return keyCode > 0
|
||||
&& keyCode < org.lwjgl.input.Keyboard.getKeyCount()
|
||||
&& org.lwjgl.input.Keyboard.isKeyDown(keyCode);
|
||||
return KeyPressHandler.isHudKeyHeld();
|
||||
}
|
||||
|
||||
public boolean hasAnyAbilities() {
|
||||
|
||||
@@ -63,6 +63,9 @@ public class GuiNpcTextField extends GuiTextField {
|
||||
if (integersOnly && getText().isEmpty() && c == '-')
|
||||
return true;
|
||||
|
||||
if ((floatsOnly || doublesOnly) && getText().isEmpty() && c == '-')
|
||||
return true;
|
||||
|
||||
for (int j : allowedSpecialChars)
|
||||
if (j == i)
|
||||
return true;
|
||||
|
||||
Reference in new issue
Block a user