2018-09-13 12:03:28 -04:00
|
|
|
package noppes.npcs.client;
|
|
|
|
|
|
2023-01-12 21:33:06 -05:00
|
|
|
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;
|
2026-02-20 18:16:52 -05:00
|
|
|
import cpw.mods.fml.relauncher.Side;
|
2026-01-26 18:38:43 -05:00
|
|
|
import kamkeel.npcs.client.renderer.lightning.LightningBolt;
|
2026-02-18 04:02:51 -05:00
|
|
|
import kamkeel.npcs.controllers.AbilityController;
|
2026-02-22 03:07:37 -05:00
|
|
|
import kamkeel.npcs.controllers.data.energycharge.EnergyChargePreviewManager;
|
2026-01-24 02:35:26 -05:00
|
|
|
import kamkeel.npcs.controllers.data.telegraph.TelegraphManager;
|
2025-02-03 03:41:01 +01:00
|
|
|
import kamkeel.npcs.network.PacketClient;
|
2026-02-21 00:03:48 +01:00
|
|
|
import kamkeel.npcs.network.packets.data.RequestProperSpawnData;
|
2025-02-03 03:57:40 +01:00
|
|
|
import kamkeel.npcs.network.packets.player.CheckPlayerValue;
|
2025-02-03 01:32:49 +01:00
|
|
|
import kamkeel.npcs.network.packets.player.InputDevicePacket;
|
2025-02-03 03:41:01 +01:00
|
|
|
import kamkeel.npcs.network.packets.player.ScreenSizePacket;
|
2026-01-22 23:07:38 -05:00
|
|
|
import kamkeel.npcs.network.packets.player.SpecialKeyStatePacket;
|
2018-09-13 12:03:28 -04:00
|
|
|
import net.minecraft.client.Minecraft;
|
2026-02-15 23:15:50 -05:00
|
|
|
import net.minecraft.client.settings.KeyBinding;
|
2024-05-14 18:32:30 -05:00
|
|
|
import net.minecraft.entity.Entity;
|
2025-02-23 06:29:53 -05:00
|
|
|
import net.minecraft.entity.player.EntityPlayer;
|
2018-09-13 12:03:28 -04:00
|
|
|
import net.minecraft.inventory.ContainerPlayer;
|
|
|
|
|
import net.minecraft.world.World;
|
|
|
|
|
import noppes.npcs.CustomNpcs;
|
|
|
|
|
import noppes.npcs.client.controllers.MusicController;
|
2022-07-13 19:27:27 -05:00
|
|
|
import noppes.npcs.client.controllers.ScriptSoundController;
|
2025-02-23 06:29:53 -05:00
|
|
|
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;
|
2025-02-20 21:40:39 -05:00
|
|
|
import noppes.npcs.client.gui.player.inventory.GuiCNPCInventory;
|
2018-09-13 12:03:28 -04:00
|
|
|
import noppes.npcs.client.renderer.RenderNPCInterface;
|
2025-11-07 20:15:49 -05:00
|
|
|
import noppes.npcs.constants.EnumRoleType;
|
2025-02-23 06:29:53 -05:00
|
|
|
import noppes.npcs.constants.MarkType;
|
|
|
|
|
import noppes.npcs.controllers.data.MarkData;
|
2025-11-07 20:15:49 -05:00
|
|
|
import noppes.npcs.controllers.data.PlayerData;
|
2025-02-23 06:29:53 -05:00
|
|
|
import noppes.npcs.entity.EntityNPCInterface;
|
2025-11-07 20:15:49 -05:00
|
|
|
import noppes.npcs.roles.RoleMount;
|
2021-10-11 07:16:10 -05:00
|
|
|
import org.lwjgl.input.Keyboard;
|
2021-10-12 02:57:32 -05:00
|
|
|
import org.lwjgl.input.Mouse;
|
2025-02-18 18:48:56 -05:00
|
|
|
import tconstruct.client.tabs.InventoryTabCustomNpc;
|
2018-09-13 12:03:28 -04:00
|
|
|
|
2025-02-23 06:29:53 -05:00
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
2022-08-31 07:53:35 -05:00
|
|
|
import static noppes.npcs.client.ClientEventHandler.renderCNPCPlayer;
|
|
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
public class ClientTickHandler {
|
|
|
|
|
private World prevWorld;
|
|
|
|
|
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};
|
2025-11-07 20:15:49 -05:00
|
|
|
private boolean lastSpecialKeyDown = false;
|
2025-03-13 17:14:45 -04:00
|
|
|
|
|
|
|
|
@SubscribeEvent(priority = EventPriority.LOWEST)
|
|
|
|
|
public void onClientTick(TickEvent.ClientTickEvent event) {
|
|
|
|
|
Minecraft mc = Minecraft.getMinecraft();
|
|
|
|
|
if ((this.prevWorld == null || mc.theWorld == null) && this.prevWorld != mc.theWorld) {
|
2025-02-12 13:16:39 -06:00
|
|
|
if (mc.theWorld == null) {
|
|
|
|
|
ClientCacheHandler.clearCache();
|
2026-02-14 03:50:28 -05:00
|
|
|
ClientAbilityState.reset();
|
2026-02-21 00:03:48 +01:00
|
|
|
RequestProperSpawnData.clear();
|
2026-02-22 03:07:37 -05:00
|
|
|
if (EnergyChargePreviewManager.ClientInstance != null) {
|
|
|
|
|
EnergyChargePreviewManager.ClientInstance.clear();
|
|
|
|
|
}
|
2025-02-12 13:16:39 -06:00
|
|
|
}
|
2025-03-13 17:14:45 -04:00
|
|
|
this.prevWorld = mc.theWorld;
|
|
|
|
|
}
|
2025-11-07 20:15:49 -05:00
|
|
|
if (event.phase == Phase.START) {
|
|
|
|
|
EntityPlayer player = mc.thePlayer;
|
|
|
|
|
if (player != null) {
|
2026-02-15 19:21:30 -05:00
|
|
|
// Only process special key when no GUI screen is open
|
|
|
|
|
boolean specialKeyDown = mc.currentScreen == null
|
|
|
|
|
&& ClientProxy.SpecialKey != null && Keyboard.isKeyDown(ClientProxy.SpecialKey.getKeyCode());
|
2025-11-07 20:15:49 -05:00
|
|
|
if (specialKeyDown != lastSpecialKeyDown) {
|
|
|
|
|
PlayerData data = CustomNpcs.proxy.getPlayerData(player);
|
|
|
|
|
if (data != null) {
|
|
|
|
|
data.setSpecialKeyDown(specialKeyDown);
|
|
|
|
|
}
|
|
|
|
|
SpecialKeyStatePacket.send(specialKeyDown);
|
|
|
|
|
lastSpecialKeyDown = specialKeyDown;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-15 23:15:50 -05:00
|
|
|
// Suppress player input during ability-controlled phases.
|
|
|
|
|
// Only suppress when no GUI screen is open (screens already capture input).
|
|
|
|
|
if (mc.currentScreen == null && ClientAbilityState.shouldSuppressMovementInput()) {
|
|
|
|
|
// Unpress movement keybinds at the source BEFORE updatePlayerMoveState() reads them.
|
|
|
|
|
KeyBinding.setKeyBindState(mc.gameSettings.keyBindForward.getKeyCode(), false);
|
|
|
|
|
KeyBinding.setKeyBindState(mc.gameSettings.keyBindBack.getKeyCode(), false);
|
|
|
|
|
KeyBinding.setKeyBindState(mc.gameSettings.keyBindLeft.getKeyCode(), false);
|
|
|
|
|
KeyBinding.setKeyBindState(mc.gameSettings.keyBindRight.getKeyCode(), false);
|
|
|
|
|
KeyBinding.setKeyBindState(mc.gameSettings.keyBindJump.getKeyCode(), false);
|
|
|
|
|
KeyBinding.setKeyBindState(mc.gameSettings.keyBindSneak.getKeyCode(), false);
|
|
|
|
|
KeyBinding.setKeyBindState(mc.gameSettings.keyBindSprint.getKeyCode(), false);
|
|
|
|
|
|
2026-02-14 03:50:28 -05:00
|
|
|
mc.thePlayer.movementInput.moveForward = 0;
|
|
|
|
|
mc.thePlayer.movementInput.moveStrafe = 0;
|
|
|
|
|
mc.thePlayer.movementInput.jump = false;
|
2026-02-15 23:15:50 -05:00
|
|
|
mc.thePlayer.movementInput.sneak = false;
|
2026-02-14 03:50:28 -05:00
|
|
|
}
|
2026-02-15 23:15:50 -05:00
|
|
|
if (mc.currentScreen == null && ClientAbilityState.shouldLockRotation()) {
|
2026-02-14 03:50:28 -05:00
|
|
|
mc.thePlayer.rotationYaw = ClientAbilityState.lockedYaw;
|
|
|
|
|
mc.thePlayer.rotationPitch = ClientAbilityState.lockedPitch;
|
|
|
|
|
mc.thePlayer.prevRotationYaw = ClientAbilityState.lockedYaw;
|
|
|
|
|
mc.thePlayer.prevRotationPitch = ClientAbilityState.lockedPitch;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-07 20:15:49 -05:00
|
|
|
if (player.ridingEntity instanceof EntityNPCInterface) {
|
|
|
|
|
EntityNPCInterface mount = (EntityNPCInterface) player.ridingEntity;
|
|
|
|
|
if (mount.advanced.role == EnumRoleType.Mount && mount.roleInterface instanceof RoleMount) {
|
|
|
|
|
RoleMount role = (RoleMount) mount.roleInterface;
|
|
|
|
|
if (!role.isSprintAllowed() && player.isSprinting()) {
|
|
|
|
|
player.setSprinting(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-03-13 17:14:45 -04:00
|
|
|
if (event.phase == Phase.END) {
|
2026-02-15 23:15:50 -05:00
|
|
|
if (mc.thePlayer != null) {
|
|
|
|
|
// Re-enforce ability locks AFTER entity update.
|
|
|
|
|
// EntityPlayerSP.onLivingUpdate() calls updatePlayerMoveState() which
|
|
|
|
|
// overwrites Phase.START suppression with actual keyboard state, causing
|
|
|
|
|
// client-predicted movement that fights the server lock. Undo it here.
|
|
|
|
|
// Skip when a GUI screen is open (screens already capture all input).
|
|
|
|
|
if (mc.currentScreen == null && ClientAbilityState.shouldSuppressMovementInput()) {
|
|
|
|
|
mc.thePlayer.movementInput.moveForward = 0;
|
|
|
|
|
mc.thePlayer.movementInput.moveStrafe = 0;
|
|
|
|
|
mc.thePlayer.movementInput.jump = false;
|
|
|
|
|
mc.thePlayer.movementInput.sneak = false;
|
|
|
|
|
|
2026-02-19 03:12:59 -05:00
|
|
|
// Zero all motion — position lock holds the player in place (server is authoritative)
|
2026-02-15 23:15:50 -05:00
|
|
|
if (!ClientAbilityState.hasAbilityMovement) {
|
|
|
|
|
mc.thePlayer.motionX = 0;
|
|
|
|
|
mc.thePlayer.motionZ = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-19 03:12:59 -05:00
|
|
|
// Zero vertical motion: grounded players can't jump, flying players are frozen in air
|
2026-02-15 23:15:50 -05:00
|
|
|
if ((ClientAbilityState.movementLocked || ClientAbilityState.positionLocked)
|
2026-02-19 03:12:59 -05:00
|
|
|
&& !ClientAbilityState.hasAbilityMovement) {
|
|
|
|
|
if (ClientAbilityState.wasFlyingAtLock) {
|
|
|
|
|
mc.thePlayer.motionY = 0;
|
|
|
|
|
} else {
|
|
|
|
|
mc.thePlayer.motionY = Math.min(mc.thePlayer.motionY, 0);
|
|
|
|
|
}
|
2026-02-15 23:15:50 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mc.currentScreen == null && ClientAbilityState.shouldLockRotation()) {
|
|
|
|
|
mc.thePlayer.rotationYaw = ClientAbilityState.lockedYaw;
|
|
|
|
|
mc.thePlayer.rotationPitch = ClientAbilityState.lockedPitch;
|
|
|
|
|
mc.thePlayer.prevRotationYaw = ClientAbilityState.lockedYaw;
|
|
|
|
|
mc.thePlayer.prevRotationPitch = ClientAbilityState.lockedPitch;
|
|
|
|
|
mc.thePlayer.rotationYawHead = ClientAbilityState.lockedYaw;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mc.theWorld != null && !mc.isGamePaused() && ClientEventHandler.hasOverlays(mc.thePlayer)) {
|
|
|
|
|
renderCNPCPlayer.itemRenderer.updateEquippedItem();
|
|
|
|
|
}
|
2025-03-13 17:14:45 -04:00
|
|
|
}
|
2026-02-20 02:16:40 -05:00
|
|
|
|
|
|
|
|
// Tick telegraph manager AFTER entity updates so telegraph positions
|
|
|
|
|
// match entity interpolation (Phase.END runs after world tick)
|
|
|
|
|
if (TelegraphManager.ClientInstance != null) {
|
|
|
|
|
TelegraphManager.ClientInstance.tick(mc.theWorld);
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-22 03:07:37 -05:00
|
|
|
// Tick packet-driven energy charge previews
|
|
|
|
|
if (EnergyChargePreviewManager.ClientInstance != null) {
|
|
|
|
|
EnergyChargePreviewManager.ClientInstance.tick(mc.theWorld);
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-20 02:16:40 -05:00
|
|
|
// Update lightning bolts for ability effects
|
|
|
|
|
LightningBolt.updateAll();
|
|
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (mc.thePlayer != null && mc.thePlayer.openContainer instanceof ContainerPlayer) {
|
|
|
|
|
if (otherContainer) {
|
2025-02-03 03:57:40 +01:00
|
|
|
PacketClient.sendClient(new CheckPlayerValue(CheckPlayerValue.Type.CheckQuestCompletion));
|
2025-03-13 17:14:45 -04:00
|
|
|
otherContainer = false;
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
otherContainer = true;
|
|
|
|
|
CustomNpcs.ticks++;
|
|
|
|
|
RenderNPCInterface.LastTextureTick++;
|
2025-03-05 22:57:24 -06:00
|
|
|
|
|
|
|
|
if (MusicController.Instance.isPlaying() && MusicController.Instance.getEntity() != null) {
|
2024-05-14 18:32:30 -05:00
|
|
|
Entity entity = MusicController.Instance.getEntity();
|
|
|
|
|
if (MusicController.Instance.getOffRange() > 0 &&
|
2024-08-22 13:42:12 -04:00
|
|
|
(Minecraft.getMinecraft().thePlayer == null ||
|
|
|
|
|
Minecraft.getMinecraft().thePlayer.getDistanceToEntity(entity) > MusicController.Instance.getOffRange() ||
|
|
|
|
|
entity.dimension != Minecraft.getMinecraft().thePlayer.dimension)) {
|
2024-05-14 18:32:30 -05:00
|
|
|
MusicController.Instance.stopMusic();
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-03-05 22:57:24 -06:00
|
|
|
|
2024-05-15 03:35:39 -05:00
|
|
|
MusicController.Instance.onUpdate();
|
2025-03-13 17:14:45 -04:00
|
|
|
ScriptSoundController.Instance.onUpdate();
|
2026-01-09 15:29:00 -05:00
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
if (Minecraft.getMinecraft().thePlayer != null && (prevWidth != mc.displayWidth || prevHeight != mc.displayHeight)) {
|
|
|
|
|
prevWidth = mc.displayWidth;
|
|
|
|
|
prevHeight = mc.displayHeight;
|
|
|
|
|
PacketClient.sendClient(new ScreenSizePacket(mc.displayWidth, mc.displayHeight));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mc.theWorld == null)
|
2025-02-23 06:29:53 -05:00
|
|
|
return;
|
|
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
if (mc.theWorld.getTotalWorldTime() % 20 == 0) { // Update every second
|
2026-02-21 00:03:48 +01:00
|
|
|
if (RequestProperSpawnData.canDoBatchUpdate())
|
|
|
|
|
RequestProperSpawnData.handleBacklog();
|
2025-02-23 06:29:53 -05:00
|
|
|
updateCompassMarks();
|
|
|
|
|
}
|
2025-03-13 17:14:45 -04:00
|
|
|
}
|
2018-09-13 12:03:28 -04:00
|
|
|
|
2026-02-20 18:16:52 -05:00
|
|
|
/**
|
|
|
|
|
* Enforce ability lock motion constraints right before entity update.
|
|
|
|
|
* The Phase.END zeroing in onClientTick can be overwritten by other mods'
|
|
|
|
|
* ClientTickEvent Phase.START handlers (e.g. flight mods re-applying gravity).
|
|
|
|
|
* PlayerTickEvent fires after all ClientTickEvent handlers but before
|
|
|
|
|
* player.onUpdate(), making this the definitive point to enforce motion locks.
|
|
|
|
|
*/
|
|
|
|
|
@SubscribeEvent(priority = EventPriority.LOWEST)
|
|
|
|
|
public void onPlayerTick(TickEvent.PlayerTickEvent event) {
|
|
|
|
|
if (event.phase != Phase.START || event.side != Side.CLIENT)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Minecraft mc = Minecraft.getMinecraft();
|
|
|
|
|
if (mc.thePlayer == null || mc.currentScreen != null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!ClientAbilityState.shouldSuppressMovementInput())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!ClientAbilityState.hasAbilityMovement) {
|
|
|
|
|
mc.thePlayer.motionX = 0;
|
|
|
|
|
mc.thePlayer.motionZ = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((ClientAbilityState.movementLocked || ClientAbilityState.positionLocked)
|
|
|
|
|
&& !ClientAbilityState.hasAbilityMovement) {
|
|
|
|
|
if (ClientAbilityState.wasFlyingAtLock) {
|
|
|
|
|
mc.thePlayer.motionY = 0;
|
|
|
|
|
} else {
|
|
|
|
|
mc.thePlayer.motionY = Math.min(mc.thePlayer.motionY, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
@SubscribeEvent
|
|
|
|
|
public void onMouse(InputEvent.MouseInputEvent event) {
|
|
|
|
|
if (Mouse.getEventButton() == -1 && Mouse.getEventDWheel() == 0)
|
|
|
|
|
return;
|
2021-10-12 02:57:32 -05:00
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
InputDevicePacket.sendMouse(Mouse.getEventButton(), Mouse.getEventDWheel(), Mouse.isButtonDown(Mouse.getEventButton()));
|
|
|
|
|
}
|
2021-10-12 02:57:32 -05:00
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
@SubscribeEvent
|
|
|
|
|
public void onKey(InputEvent.KeyInputEvent event) {
|
2026-02-15 23:15:50 -05:00
|
|
|
Minecraft mc = Minecraft.getMinecraft();
|
|
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
if (ClientProxy.NPCButton.isPressed()) {
|
|
|
|
|
if (mc.currentScreen == null) {
|
2025-02-18 18:48:56 -05:00
|
|
|
InventoryTabCustomNpc.tabHelper();
|
2025-03-13 17:14:45 -04:00
|
|
|
} else if (mc.currentScreen instanceof GuiCNPCInventory)
|
|
|
|
|
mc.setIngameFocus();
|
|
|
|
|
}
|
2021-10-11 07:16:10 -05:00
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
if (!Keyboard.isRepeatEvent()) {
|
|
|
|
|
int key = Keyboard.getEventKey();
|
|
|
|
|
boolean keyDown = Keyboard.isKeyDown(key);
|
2021-11-13 13:32:33 -06:00
|
|
|
|
2026-02-15 23:15:50 -05:00
|
|
|
// 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
|
2026-02-18 05:13:51 -05:00
|
|
|
&& ClientAbilityState.shouldSuppressMovementInput() && isMovementKey(key)) {
|
2026-02-15 23:15:50 -05:00
|
|
|
// Unpress the keybind so vanilla doesn't process it
|
|
|
|
|
KeyBinding.setKeyBindState(key, false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-03 01:32:49 +01:00
|
|
|
InputDevicePacket.sendKeyboard(key, keyDown);
|
2025-03-13 17:14:45 -04:00
|
|
|
}
|
|
|
|
|
}
|
2018-09-13 12:03:28 -04:00
|
|
|
|
2026-02-15 23:15:50 -05:00
|
|
|
/**
|
|
|
|
|
* 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();
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
private boolean isIgnoredKey(int key) {
|
|
|
|
|
int[] var2 = this.ignoreKeys;
|
|
|
|
|
int var3 = var2.length;
|
2021-10-11 07:16:10 -05:00
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
for (int var4 = 0; var4 < var3; ++var4) {
|
|
|
|
|
int i = var2[var4];
|
|
|
|
|
if (i == key) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-10-11 07:16:10 -05:00
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
return false;
|
|
|
|
|
}
|
2025-02-23 06:29:53 -05:00
|
|
|
|
|
|
|
|
private final int SCAN_RANGE = 128;
|
2025-03-13 17:14:45 -04:00
|
|
|
|
2025-02-23 06:29:53 -05:00
|
|
|
private void updateCompassMarks() {
|
|
|
|
|
Minecraft mc = Minecraft.getMinecraft();
|
|
|
|
|
EntityPlayer player = mc.thePlayer;
|
2025-02-23 15:38:42 -05:00
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
if (player == null || mc.theWorld == null)
|
2025-03-05 16:09:14 -05:00
|
|
|
return;
|
|
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
if (ClientHudManager.getInstance() == null || ClientHudManager.getInstance().getHudComponents() == null)
|
2025-03-05 16:09:14 -05:00
|
|
|
return;
|
|
|
|
|
|
2025-02-23 15:38:42 -05:00
|
|
|
// Update compass
|
|
|
|
|
HudComponent compass = ClientHudManager.getInstance()
|
|
|
|
|
.getHudComponents().get(EnumHudComponent.QuestCompass);
|
|
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
if (!(compass instanceof CompassHudComponent))
|
2025-03-05 16:09:14 -05:00
|
|
|
return;
|
|
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
if (!compass.enabled)
|
2025-02-23 15:38:42 -05:00
|
|
|
return;
|
|
|
|
|
|
2025-02-23 06:29:53 -05:00
|
|
|
ArrayList<CompassHudComponent.MarkTargetEntry> marks = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
// Scan entities in loaded chunks
|
2025-03-13 17:14:45 -04:00
|
|
|
for (Object entity : mc.theWorld.loadedEntityList) {
|
|
|
|
|
if (entity instanceof EntityNPCInterface) {
|
2025-02-23 06:29:53 -05:00
|
|
|
EntityNPCInterface npc = (EntityNPCInterface) entity;
|
|
|
|
|
|
2025-03-13 17:14:45 -04:00
|
|
|
if (npc.dimension != player.dimension)
|
2025-02-23 15:38:42 -05:00
|
|
|
continue;
|
|
|
|
|
|
2025-02-23 06:29:53 -05:00
|
|
|
// Check distance
|
2025-03-13 17:14:45 -04:00
|
|
|
if (player.getDistanceToEntity(npc) > SCAN_RANGE)
|
2025-02-23 06:29:53 -05:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// Get marks
|
|
|
|
|
MarkData markData = MarkData.get(npc);
|
2025-03-13 17:14:45 -04:00
|
|
|
for (MarkData.Mark mark : markData.marks) {
|
|
|
|
|
if (mark.getType() != MarkType.NONE &&
|
2025-02-23 06:29:53 -05:00
|
|
|
mark.availability.isAvailable(player)) {
|
|
|
|
|
marks.add(new CompassHudComponent.MarkTargetEntry(
|
2025-03-08 20:30:10 -05:00
|
|
|
npc.posX,
|
|
|
|
|
npc.posZ,
|
2025-02-23 06:29:53 -05:00
|
|
|
mark.getType(),
|
|
|
|
|
mark.color
|
|
|
|
|
));
|
|
|
|
|
break; // Only show first valid mark per NPC
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-23 15:38:42 -05:00
|
|
|
((CompassHudComponent) compass).updateMarkTargets(marks);
|
2025-02-23 06:29:53 -05:00
|
|
|
}
|
2018-09-13 12:03:28 -04:00
|
|
|
}
|