Added improved player input contexts.
This commit is contained in:
parent
3e26a33f5a
commit
606d0ea674
|
@ -29,6 +29,7 @@ public class Client implements Runnable {
|
||||||
private final ClientConfig config;
|
private final ClientConfig config;
|
||||||
private final CommunicationHandler communicationHandler;
|
private final CommunicationHandler communicationHandler;
|
||||||
private final InputHandler inputHandler;
|
private final InputHandler inputHandler;
|
||||||
|
private final Camera camera;
|
||||||
private GameRenderer gameRenderer;
|
private GameRenderer gameRenderer;
|
||||||
private SoundManager soundManager;
|
private SoundManager soundManager;
|
||||||
private long lastPlayerUpdate = 0;
|
private long lastPlayerUpdate = 0;
|
||||||
|
@ -43,11 +44,12 @@ public class Client implements Runnable {
|
||||||
|
|
||||||
public Client(ClientConfig config) {
|
public Client(ClientConfig config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
this.camera = new Camera();
|
||||||
this.players = new ConcurrentHashMap<>();
|
this.players = new ConcurrentHashMap<>();
|
||||||
this.teams = new ConcurrentHashMap<>();
|
this.teams = new ConcurrentHashMap<>();
|
||||||
this.projectiles = new ConcurrentHashMap<>();
|
this.projectiles = new ConcurrentHashMap<>();
|
||||||
this.communicationHandler = new CommunicationHandler(this);
|
this.communicationHandler = new CommunicationHandler(this);
|
||||||
this.inputHandler = new InputHandler(this, communicationHandler);
|
this.inputHandler = new InputHandler(this, communicationHandler, camera);
|
||||||
this.chat = new Chat();
|
this.chat = new Chat();
|
||||||
this.mainThreadActions = new ConcurrentLinkedQueue<>();
|
this.mainThreadActions = new ConcurrentLinkedQueue<>();
|
||||||
}
|
}
|
||||||
|
@ -78,7 +80,7 @@ public class Client implements Runnable {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gameRenderer = new GameRenderer(this, inputHandler);
|
gameRenderer = new GameRenderer(this, inputHandler, camera);
|
||||||
soundManager = new SoundManager();
|
soundManager = new SoundManager();
|
||||||
|
|
||||||
long lastFrameAt = System.currentTimeMillis();
|
long lastFrameAt = System.currentTimeMillis();
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package nl.andrewl.aos2_client.control;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a particular context in which player input is obtained. Different
|
||||||
|
* contexts do different things with the input. The main game, for example, will
|
||||||
|
* move the player when WASD keys are pressed, and a chatting context might type
|
||||||
|
* out the keys the player presses into a chat buffer. Contexts may choose to
|
||||||
|
* implement only some specified methods here.
|
||||||
|
*/
|
||||||
|
public interface InputContext {
|
||||||
|
default void onEnable() {}
|
||||||
|
default void onDisable() {}
|
||||||
|
|
||||||
|
default void keyPress(long window, int key, int mods) {}
|
||||||
|
default void keyRelease(long window, int key, int mods) {}
|
||||||
|
default void keyRepeat(long window, int key, int mods) {}
|
||||||
|
default void charInput(long window, int codePoint) {}
|
||||||
|
|
||||||
|
default void mouseButtonPress(long window, int button, int mods) {}
|
||||||
|
default void mouseButtonRelease(long window, int button, int mods) {}
|
||||||
|
default void mouseScroll(long window, double xOffset, double yOffset) {}
|
||||||
|
default void mouseCursorPos(long window, double xPos, double yPos) {}
|
||||||
|
}
|
|
@ -1,14 +1,11 @@
|
||||||
package nl.andrewl.aos2_client.control;
|
package nl.andrewl.aos2_client.control;
|
||||||
|
|
||||||
|
import nl.andrewl.aos2_client.Camera;
|
||||||
import nl.andrewl.aos2_client.Client;
|
import nl.andrewl.aos2_client.Client;
|
||||||
import nl.andrewl.aos2_client.CommunicationHandler;
|
import nl.andrewl.aos2_client.CommunicationHandler;
|
||||||
import nl.andrewl.aos2_client.model.ClientPlayer;
|
import nl.andrewl.aos2_client.control.context.ChattingContext;
|
||||||
import nl.andrewl.aos_core.model.item.BlockItemStack;
|
import nl.andrewl.aos2_client.control.context.ExitMenuContext;
|
||||||
import nl.andrewl.aos_core.model.item.GunItemStack;
|
import nl.andrewl.aos2_client.control.context.NormalContext;
|
||||||
import nl.andrewl.aos_core.model.world.Hit;
|
|
||||||
import nl.andrewl.aos_core.net.client.BlockColorMessage;
|
|
||||||
import nl.andrewl.aos_core.net.client.ChatWrittenMessage;
|
|
||||||
import nl.andrewl.aos_core.net.client.ClientInputState;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class which manages the player's input, and sending it to the server.
|
* Class which manages the player's input, and sending it to the server.
|
||||||
|
@ -19,236 +16,81 @@ public class InputHandler {
|
||||||
|
|
||||||
private long windowId;
|
private long windowId;
|
||||||
|
|
||||||
private ClientInputState lastInputState = null;
|
private final NormalContext normalContext;
|
||||||
|
private final ChattingContext chattingContext;
|
||||||
|
private final ExitMenuContext exitMenuContext;
|
||||||
|
|
||||||
private boolean forward;
|
private InputContext activeContext;
|
||||||
private boolean backward;
|
|
||||||
private boolean left;
|
|
||||||
private boolean right;
|
|
||||||
private boolean jumping;
|
|
||||||
private boolean crouching;
|
|
||||||
private boolean sprinting;
|
|
||||||
private boolean hitting;
|
|
||||||
private boolean interacting;
|
|
||||||
private boolean reloading;
|
|
||||||
private int selectedInventoryIndex;
|
|
||||||
|
|
||||||
private boolean debugEnabled;
|
public InputHandler(Client client, CommunicationHandler comm, Camera cam) {
|
||||||
|
|
||||||
private boolean chatting;
|
|
||||||
private StringBuffer chatText = new StringBuffer();
|
|
||||||
|
|
||||||
|
|
||||||
public InputHandler(Client client, CommunicationHandler comm) {
|
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.comm = comm;
|
this.comm = comm;
|
||||||
|
this.normalContext = new NormalContext(this, cam);
|
||||||
|
this.chattingContext = new ChattingContext(this);
|
||||||
|
this.exitMenuContext = new ExitMenuContext(this);
|
||||||
|
this.activeContext = normalContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWindowId(long windowId) {
|
public void setWindowId(long windowId) {
|
||||||
this.windowId = windowId;
|
this.windowId = windowId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateInputState() {
|
public InputContext getActiveContext() {
|
||||||
ClientInputState currentInputState = new ClientInputState(
|
return activeContext;
|
||||||
comm.getClientId(),
|
|
||||||
forward, backward, left, right,
|
|
||||||
jumping, crouching, sprinting,
|
|
||||||
hitting, interacting, reloading,
|
|
||||||
selectedInventoryIndex
|
|
||||||
);
|
|
||||||
if (!currentInputState.equals(lastInputState)) {
|
|
||||||
comm.sendDatagramPacket(currentInputState);
|
|
||||||
lastInputState = currentInputState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientPlayer player = client.getMyPlayer();
|
private void switchToContext(InputContext newContext) {
|
||||||
|
if (newContext.equals(activeContext)) return;
|
||||||
|
activeContext.onDisable();
|
||||||
|
newContext.onEnable();
|
||||||
|
activeContext = newContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isForward() {
|
public void switchToNormalContext() {
|
||||||
return forward;
|
switchToContext(normalContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setForward(boolean forward) {
|
public void switchToChattingContext() {
|
||||||
if (chatting) return;
|
switchToContext(chattingContext);
|
||||||
this.forward = forward;
|
|
||||||
updateInputState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBackward() {
|
public void switchToExitMenuContext() {
|
||||||
return backward;
|
switchToContext(exitMenuContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBackward(boolean backward) {
|
public NormalContext getNormalContext() {
|
||||||
if (chatting) return;
|
return normalContext;
|
||||||
this.backward = backward;
|
|
||||||
updateInputState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLeft() {
|
public ChattingContext getChattingContext() {
|
||||||
return left;
|
return chattingContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLeft(boolean left) {
|
public ExitMenuContext getExitMenuContext() {
|
||||||
if (chatting) return;
|
return exitMenuContext;
|
||||||
this.left = left;
|
|
||||||
updateInputState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRight() {
|
public boolean isNormalContextActive() {
|
||||||
return right;
|
return normalContext.equals(activeContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRight(boolean right) {
|
public boolean isChattingContextActive() {
|
||||||
if (chatting) return;
|
return chattingContext.equals(activeContext);
|
||||||
this.right = right;
|
|
||||||
updateInputState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isJumping() {
|
public boolean isExitMenuContextActive() {
|
||||||
return jumping;
|
return exitMenuContext.equals(activeContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setJumping(boolean jumping) {
|
public Client getClient() {
|
||||||
if (chatting) return;
|
return client;
|
||||||
this.jumping = jumping;
|
|
||||||
updateInputState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCrouching() {
|
public CommunicationHandler getComm() {
|
||||||
return crouching;
|
return comm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCrouching(boolean crouching) {
|
public long getWindowId() {
|
||||||
if (chatting) return;
|
return windowId;
|
||||||
this.crouching = crouching;
|
|
||||||
updateInputState();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSprinting() {
|
|
||||||
return sprinting;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSprinting(boolean sprinting) {
|
|
||||||
if (chatting) return;
|
|
||||||
this.sprinting = sprinting;
|
|
||||||
updateInputState();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isHitting() {
|
|
||||||
return hitting;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHitting(boolean hitting) {
|
|
||||||
if (chatting) return;
|
|
||||||
this.hitting = hitting;
|
|
||||||
updateInputState();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isInteracting() {
|
|
||||||
return interacting;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInteracting(boolean interacting) {
|
|
||||||
if (chatting) return;
|
|
||||||
this.interacting = interacting;
|
|
||||||
updateInputState();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isReloading() {
|
|
||||||
return reloading;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReloading(boolean reloading) {
|
|
||||||
if (chatting) return;
|
|
||||||
this.reloading = reloading;
|
|
||||||
updateInputState();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSelectedInventoryIndex() {
|
|
||||||
return selectedInventoryIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSelectedInventoryIndex(int selectedInventoryIndex) {
|
|
||||||
if (chatting) return;
|
|
||||||
this.selectedInventoryIndex = selectedInventoryIndex;
|
|
||||||
updateInputState();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDebugEnabled() {
|
|
||||||
return debugEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void toggleDebugEnabled() {
|
|
||||||
this.debugEnabled = !debugEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableChatting() {
|
|
||||||
if (chatting) return;
|
|
||||||
setForward(false);
|
|
||||||
setBackward(false);
|
|
||||||
setLeft(false);
|
|
||||||
setRight(false);
|
|
||||||
setJumping(false);
|
|
||||||
setCrouching(false);
|
|
||||||
setSprinting(false);
|
|
||||||
setReloading(false);
|
|
||||||
chatting = true;
|
|
||||||
chatText = new StringBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isChatting() {
|
|
||||||
return chatting;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancelChatting() {
|
|
||||||
chatting = false;
|
|
||||||
chatText.delete(0, chatText.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void appendToChat(int codePoint) {
|
|
||||||
if (!chatting || chatText.length() + 1 > 120) return;
|
|
||||||
chatText.appendCodePoint(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void appendToChat(String s) {
|
|
||||||
if (!chatting || chatText.length() + s.length() > 120) return;
|
|
||||||
chatText.append(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteFromChat() {
|
|
||||||
if (!chatting || chatText.length() == 0) return;
|
|
||||||
chatText.deleteCharAt(chatText.length() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getChatText() {
|
|
||||||
return chatText.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendChat() {
|
|
||||||
if (!chatting) return;
|
|
||||||
String text = chatText.toString().trim();
|
|
||||||
cancelChatting();
|
|
||||||
if (!text.isBlank()) {
|
|
||||||
client.getCommunicationHandler().sendMessage(new ChatWrittenMessage(text));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isScopeEnabled() {
|
|
||||||
return interacting &&
|
|
||||||
client.getMyPlayer().getInventory().getSelectedItemStack() instanceof GunItemStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pickBlock() {
|
|
||||||
var player = client.getMyPlayer();
|
|
||||||
if (player.getInventory().getSelectedItemStack() instanceof BlockItemStack stack) {
|
|
||||||
Hit hit = client.getWorld().getLookingAtPos(player.getEyePosition(), player.getViewVector(), 50);
|
|
||||||
if (hit != null) {
|
|
||||||
byte selectedBlock = client.getWorld().getBlockAt(hit.pos().x, hit.pos().y, hit.pos().z);
|
|
||||||
if (selectedBlock > 0) {
|
|
||||||
stack.setSelectedValue(selectedBlock);
|
|
||||||
comm.sendDatagramPacket(new BlockColorMessage(player.getId(), selectedBlock));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,6 @@ public class PlayerCharacterInputCallback implements GLFWCharCallbackI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invoke(long window, int codepoint) {
|
public void invoke(long window, int codepoint) {
|
||||||
if (inputHandler.isChatting()) {
|
inputHandler.getActiveContext().charInput(window, codepoint);
|
||||||
inputHandler.appendToChat(codepoint);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,58 +13,10 @@ public class PlayerInputKeyCallback implements GLFWKeyCallbackI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invoke(long window, int key, int scancode, int action, int mods) {
|
public void invoke(long window, int key, int scancode, int action, int mods) {
|
||||||
if (action == GLFW_PRESS) {
|
switch (action) {
|
||||||
switch (key) {
|
case GLFW_PRESS -> inputHandler.getActiveContext().keyPress(window, key, mods);
|
||||||
case GLFW_KEY_W -> inputHandler.setForward(true);
|
case GLFW_RELEASE -> inputHandler.getActiveContext().keyRelease(window, key, mods);
|
||||||
case GLFW_KEY_A -> inputHandler.setLeft(true);
|
case GLFW_REPEAT -> inputHandler.getActiveContext().keyRepeat(window, key, mods);
|
||||||
case GLFW_KEY_S -> inputHandler.setBackward(true);
|
|
||||||
case GLFW_KEY_D -> inputHandler.setRight(true);
|
|
||||||
case GLFW_KEY_SPACE -> inputHandler.setJumping(true);
|
|
||||||
case GLFW_KEY_LEFT_CONTROL -> inputHandler.setCrouching(true);
|
|
||||||
case GLFW_KEY_LEFT_SHIFT -> inputHandler.setSprinting(true);
|
|
||||||
case GLFW_KEY_R -> inputHandler.setReloading(true);
|
|
||||||
|
|
||||||
case GLFW_KEY_BACKSPACE -> inputHandler.deleteFromChat();
|
|
||||||
case GLFW_KEY_ENTER -> inputHandler.sendChat();
|
|
||||||
|
|
||||||
case GLFW_KEY_1 -> inputHandler.setSelectedInventoryIndex(0);
|
|
||||||
case GLFW_KEY_2 -> inputHandler.setSelectedInventoryIndex(1);
|
|
||||||
case GLFW_KEY_3 -> inputHandler.setSelectedInventoryIndex(2);
|
|
||||||
case GLFW_KEY_4 -> inputHandler.setSelectedInventoryIndex(3);
|
|
||||||
|
|
||||||
case GLFW_KEY_F3 -> inputHandler.toggleDebugEnabled();
|
|
||||||
|
|
||||||
case GLFW_KEY_ESCAPE -> {
|
|
||||||
if (inputHandler.isChatting()) {
|
|
||||||
inputHandler.cancelChatting();
|
|
||||||
} else {
|
|
||||||
glfwSetWindowShouldClose(window, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (action == GLFW_RELEASE) {
|
|
||||||
switch (key) {
|
|
||||||
case GLFW_KEY_W -> inputHandler.setForward(false);
|
|
||||||
case GLFW_KEY_A -> inputHandler.setLeft(false);
|
|
||||||
case GLFW_KEY_S -> inputHandler.setBackward(false);
|
|
||||||
case GLFW_KEY_D -> inputHandler.setRight(false);
|
|
||||||
case GLFW_KEY_SPACE -> inputHandler.setJumping(false);
|
|
||||||
case GLFW_KEY_LEFT_CONTROL -> inputHandler.setCrouching(false);
|
|
||||||
case GLFW_KEY_LEFT_SHIFT -> inputHandler.setSprinting(false);
|
|
||||||
case GLFW_KEY_R -> inputHandler.setReloading(false);
|
|
||||||
|
|
||||||
case GLFW_KEY_T -> inputHandler.enableChatting();
|
|
||||||
case GLFW_KEY_SLASH -> {
|
|
||||||
if (!inputHandler.isChatting()) {
|
|
||||||
inputHandler.enableChatting();
|
|
||||||
inputHandler.appendToChat("/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (action == GLFW_REPEAT) {
|
|
||||||
switch (key) {
|
|
||||||
case GLFW_KEY_BACKSPACE -> inputHandler.deleteFromChat();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,8 @@ package nl.andrewl.aos2_client.control;
|
||||||
|
|
||||||
import org.lwjgl.glfw.GLFWMouseButtonCallbackI;
|
import org.lwjgl.glfw.GLFWMouseButtonCallbackI;
|
||||||
|
|
||||||
import static org.lwjgl.glfw.GLFW.*;
|
import static org.lwjgl.glfw.GLFW.GLFW_PRESS;
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_RELEASE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback that's called when the player clicks with their mouse.
|
* Callback that's called when the player clicks with their mouse.
|
||||||
|
@ -16,17 +17,9 @@ public class PlayerInputMouseClickCallback implements GLFWMouseButtonCallbackI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invoke(long window, int button, int action, int mods) {
|
public void invoke(long window, int button, int action, int mods) {
|
||||||
if (action == GLFW_PRESS) {
|
switch (action) {
|
||||||
switch (button) {
|
case GLFW_PRESS -> inputHandler.getActiveContext().mouseButtonPress(window, button, mods);
|
||||||
case GLFW_MOUSE_BUTTON_1 -> inputHandler.setHitting(true);
|
case GLFW_RELEASE -> inputHandler.getActiveContext().mouseButtonRelease(window, button, mods);
|
||||||
case GLFW_MOUSE_BUTTON_2 -> inputHandler.setInteracting(true);
|
|
||||||
case GLFW_MOUSE_BUTTON_3 -> inputHandler.pickBlock();
|
|
||||||
}
|
|
||||||
} else if (action == GLFW_RELEASE) {
|
|
||||||
switch (button) {
|
|
||||||
case GLFW_MOUSE_BUTTON_1 -> inputHandler.setHitting(false);
|
|
||||||
case GLFW_MOUSE_BUTTON_2 -> inputHandler.setInteracting(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,16 @@
|
||||||
package nl.andrewl.aos2_client.control;
|
package nl.andrewl.aos2_client.control;
|
||||||
|
|
||||||
import nl.andrewl.aos2_client.Client;
|
|
||||||
import nl.andrewl.aos2_client.CommunicationHandler;
|
|
||||||
import nl.andrewl.aos_core.model.item.BlockItemStack;
|
|
||||||
import nl.andrewl.aos_core.net.client.BlockColorMessage;
|
|
||||||
import org.lwjgl.glfw.GLFWScrollCallbackI;
|
import org.lwjgl.glfw.GLFWScrollCallbackI;
|
||||||
|
|
||||||
public class PlayerInputMouseScrollCallback implements GLFWScrollCallbackI {
|
public class PlayerInputMouseScrollCallback implements GLFWScrollCallbackI {
|
||||||
private final Client client;
|
private final InputHandler inputHandler;
|
||||||
private final CommunicationHandler comm;
|
|
||||||
|
|
||||||
public PlayerInputMouseScrollCallback(Client client) {
|
public PlayerInputMouseScrollCallback(InputHandler inputHandler) {
|
||||||
this.client = client;
|
this.inputHandler = inputHandler;
|
||||||
this.comm = client.getCommunicationHandler();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invoke(long window, double xoffset, double yoffset) {
|
public void invoke(long window, double xoffset, double yoffset) {
|
||||||
if (client.getMyPlayer().getInventory().getSelectedItemStack() instanceof BlockItemStack stack) {
|
inputHandler.getActiveContext().mouseScroll(window, xoffset, yoffset);
|
||||||
if (yoffset < 0) {
|
|
||||||
stack.setSelectedValue((byte) (stack.getSelectedValue() - 1));
|
|
||||||
} else if (yoffset > 0) {
|
|
||||||
stack.setSelectedValue((byte) (stack.getSelectedValue() + 1));
|
|
||||||
}
|
|
||||||
comm.sendDatagramPacket(new BlockColorMessage(client.getMyPlayer().getId(), stack.getSelectedValue()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,64 +1,17 @@
|
||||||
package nl.andrewl.aos2_client.control;
|
package nl.andrewl.aos2_client.control;
|
||||||
|
|
||||||
import nl.andrewl.aos2_client.Camera;
|
|
||||||
import nl.andrewl.aos2_client.Client;
|
|
||||||
import nl.andrewl.aos2_client.CommunicationHandler;
|
|
||||||
import nl.andrewl.aos2_client.config.ClientConfig;
|
|
||||||
import nl.andrewl.aos_core.net.client.ClientOrientationState;
|
|
||||||
import org.lwjgl.glfw.GLFWCursorPosCallbackI;
|
import org.lwjgl.glfw.GLFWCursorPosCallbackI;
|
||||||
|
|
||||||
import java.util.concurrent.ForkJoinPool;
|
|
||||||
|
|
||||||
import static org.lwjgl.glfw.GLFW.glfwGetCursorPos;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback that's called when the player's cursor position updates. This means
|
|
||||||
* the player is looking around.
|
|
||||||
*/
|
|
||||||
public class PlayerViewCursorCallback implements GLFWCursorPosCallbackI {
|
public class PlayerViewCursorCallback implements GLFWCursorPosCallbackI {
|
||||||
/**
|
|
||||||
* The number of milliseconds to wait before sending orientation updates,
|
|
||||||
* to prevent overloading the server.
|
|
||||||
*/
|
|
||||||
private static final int ORIENTATION_UPDATE_LIMIT = 20;
|
|
||||||
|
|
||||||
private final ClientConfig.InputConfig config;
|
private final InputHandler inputHandler;
|
||||||
private final Client client;
|
|
||||||
private final Camera camera;
|
|
||||||
private final CommunicationHandler comm;
|
|
||||||
private float lastMouseCursorX;
|
|
||||||
private float lastMouseCursorY;
|
|
||||||
private long lastOrientationUpdateSentAt = 0L;
|
|
||||||
|
|
||||||
public PlayerViewCursorCallback(Client client, Camera cam) {
|
public PlayerViewCursorCallback(InputHandler inputHandler) {
|
||||||
this.config = client.getConfig().input;
|
this.inputHandler = inputHandler;
|
||||||
this.client = client;
|
|
||||||
this.camera = cam;
|
|
||||||
this.comm = client.getCommunicationHandler();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invoke(long window, double xpos, double ypos) {
|
public void invoke(long window, double xpos, double ypos) {
|
||||||
double[] xb = new double[1];
|
inputHandler.getActiveContext().mouseCursorPos(window, xpos, ypos);
|
||||||
double[] yb = new double[1];
|
|
||||||
glfwGetCursorPos(window, xb, yb);
|
|
||||||
float x = (float) xb[0];
|
|
||||||
float y = (float) yb[0];
|
|
||||||
float dx = x - lastMouseCursorX;
|
|
||||||
float dy = y - lastMouseCursorY;
|
|
||||||
lastMouseCursorX = x;
|
|
||||||
lastMouseCursorY = y;
|
|
||||||
float trueSensitivity = config.mouseSensitivity;
|
|
||||||
if (client.getInputHandler().isScopeEnabled()) trueSensitivity *= 0.1f;
|
|
||||||
client.getMyPlayer().setOrientation(
|
|
||||||
client.getMyPlayer().getOrientation().x - dx * trueSensitivity,
|
|
||||||
client.getMyPlayer().getOrientation().y - dy * trueSensitivity
|
|
||||||
);
|
|
||||||
camera.setOrientationToPlayer(client.getMyPlayer());
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
if (lastOrientationUpdateSentAt + ORIENTATION_UPDATE_LIMIT < now) {
|
|
||||||
ForkJoinPool.commonPool().submit(() -> comm.sendDatagramPacket(ClientOrientationState.fromPlayer(client.getMyPlayer())));
|
|
||||||
lastOrientationUpdateSentAt = now;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
package nl.andrewl.aos2_client.control.context;
|
||||||
|
|
||||||
|
import nl.andrewl.aos2_client.control.InputContext;
|
||||||
|
import nl.andrewl.aos2_client.control.InputHandler;
|
||||||
|
import nl.andrewl.aos2_client.util.WindowUtils;
|
||||||
|
import nl.andrewl.aos_core.net.client.ChatWrittenMessage;
|
||||||
|
|
||||||
|
import static org.lwjgl.glfw.GLFW.*;
|
||||||
|
|
||||||
|
public class ChattingContext implements InputContext {
|
||||||
|
private static final int MAX_LENGTH = 120;
|
||||||
|
|
||||||
|
private final InputHandler inputHandler;
|
||||||
|
|
||||||
|
private final StringBuffer chatBuffer = new StringBuffer(MAX_LENGTH);
|
||||||
|
|
||||||
|
public ChattingContext(InputHandler inputHandler) {
|
||||||
|
this.inputHandler = inputHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void appendToChat(int codePoint) {
|
||||||
|
appendToChat(Character.toString(codePoint));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void appendToChat(String content) {
|
||||||
|
if (chatBuffer.length() + content.length() > MAX_LENGTH) return;
|
||||||
|
chatBuffer.append(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteFromChat() {
|
||||||
|
if (chatBuffer.length() > 0) {
|
||||||
|
chatBuffer.deleteCharAt(chatBuffer.length() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearChatBuffer() {
|
||||||
|
chatBuffer.delete(0, chatBuffer.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendChat() {
|
||||||
|
String text = chatBuffer.toString().trim();
|
||||||
|
if (!text.isBlank()) {
|
||||||
|
inputHandler.getComm().sendMessage(new ChatWrittenMessage(text));
|
||||||
|
}
|
||||||
|
inputHandler.switchToNormalContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChatBufferText() {
|
||||||
|
return new String(chatBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
clearChatBuffer();
|
||||||
|
if (inputHandler.getClient().getConfig().display.captureCursor) {
|
||||||
|
WindowUtils.freeCursor(inputHandler.getWindowId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
clearChatBuffer();
|
||||||
|
if (inputHandler.getClient().getConfig().display.captureCursor) {
|
||||||
|
WindowUtils.captureCursor(inputHandler.getWindowId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPress(long window, int key, int mods) {
|
||||||
|
switch (key) {
|
||||||
|
case GLFW_KEY_BACKSPACE -> deleteFromChat();
|
||||||
|
case GLFW_KEY_ENTER -> sendChat();
|
||||||
|
case GLFW_KEY_ESCAPE -> inputHandler.switchToNormalContext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyRepeat(long window, int key, int mods) {
|
||||||
|
switch (key) {
|
||||||
|
case GLFW_KEY_BACKSPACE -> deleteFromChat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void charInput(long window, int codePoint) {
|
||||||
|
appendToChat(codePoint);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package nl.andrewl.aos2_client.control.context;
|
||||||
|
|
||||||
|
import nl.andrewl.aos2_client.control.InputContext;
|
||||||
|
import nl.andrewl.aos2_client.control.InputHandler;
|
||||||
|
import nl.andrewl.aos2_client.util.WindowUtils;
|
||||||
|
|
||||||
|
import static org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE;
|
||||||
|
import static org.lwjgl.glfw.GLFW.glfwSetWindowShouldClose;
|
||||||
|
|
||||||
|
public class ExitMenuContext implements InputContext {
|
||||||
|
private final InputHandler inputHandler;
|
||||||
|
|
||||||
|
public ExitMenuContext(InputHandler inputHandler) {
|
||||||
|
this.inputHandler = inputHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
if (inputHandler.getClient().getConfig().display.captureCursor) {
|
||||||
|
WindowUtils.freeCursor(inputHandler.getWindowId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
if (inputHandler.getClient().getConfig().display.captureCursor) {
|
||||||
|
WindowUtils.captureCursor(inputHandler.getWindowId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPress(long window, int key, int mods) {
|
||||||
|
switch (key) {
|
||||||
|
case GLFW_KEY_ESCAPE -> glfwSetWindowShouldClose(window, true);
|
||||||
|
default -> inputHandler.switchToNormalContext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,283 @@
|
||||||
|
package nl.andrewl.aos2_client.control.context;
|
||||||
|
|
||||||
|
import nl.andrewl.aos2_client.Camera;
|
||||||
|
import nl.andrewl.aos2_client.control.InputContext;
|
||||||
|
import nl.andrewl.aos2_client.control.InputHandler;
|
||||||
|
import nl.andrewl.aos_core.model.item.BlockItemStack;
|
||||||
|
import nl.andrewl.aos_core.model.item.GunItemStack;
|
||||||
|
import nl.andrewl.aos_core.model.item.ItemStack;
|
||||||
|
import nl.andrewl.aos_core.model.world.Hit;
|
||||||
|
import nl.andrewl.aos_core.net.client.BlockColorMessage;
|
||||||
|
import nl.andrewl.aos_core.net.client.ClientInputState;
|
||||||
|
import nl.andrewl.aos_core.net.client.ClientOrientationState;
|
||||||
|
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
|
||||||
|
import static org.lwjgl.glfw.GLFW.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The normal input context that occurs when the player is active in the game.
|
||||||
|
* This includes moving around, interacting with their inventory, moving their
|
||||||
|
* view, and so on.
|
||||||
|
*/
|
||||||
|
public class NormalContext implements InputContext {
|
||||||
|
/**
|
||||||
|
* The number of milliseconds to wait before sending orientation updates,
|
||||||
|
* to prevent overloading the server.
|
||||||
|
*/
|
||||||
|
private static final int ORIENTATION_UPDATE_LIMIT = 20;
|
||||||
|
|
||||||
|
private final InputHandler inputHandler;
|
||||||
|
private final Camera camera;
|
||||||
|
|
||||||
|
private ClientInputState lastInputState = null;
|
||||||
|
|
||||||
|
private boolean forward;
|
||||||
|
private boolean backward;
|
||||||
|
private boolean left;
|
||||||
|
private boolean right;
|
||||||
|
private boolean jumping;
|
||||||
|
private boolean crouching;
|
||||||
|
private boolean sprinting;
|
||||||
|
private boolean hitting;
|
||||||
|
private boolean interacting;
|
||||||
|
private boolean reloading;
|
||||||
|
private int selectedInventoryIndex;
|
||||||
|
|
||||||
|
private boolean debugEnabled;
|
||||||
|
|
||||||
|
private float lastMouseCursorX;
|
||||||
|
private float lastMouseCursorY;
|
||||||
|
private long lastOrientationUpdateSentAt = 0L;
|
||||||
|
|
||||||
|
public NormalContext(InputHandler inputHandler, Camera camera) {
|
||||||
|
this.inputHandler = inputHandler;
|
||||||
|
this.camera = camera;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateInputState() {
|
||||||
|
var comm = inputHandler.getComm();
|
||||||
|
ClientInputState currentInputState = new ClientInputState(
|
||||||
|
comm.getClientId(),
|
||||||
|
forward, backward, left, right,
|
||||||
|
jumping, crouching, sprinting,
|
||||||
|
hitting, interacting, reloading,
|
||||||
|
selectedInventoryIndex
|
||||||
|
);
|
||||||
|
if (!currentInputState.equals(lastInputState)) {
|
||||||
|
comm.sendDatagramPacket(currentInputState);
|
||||||
|
lastInputState = currentInputState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetInputState() {
|
||||||
|
forward = false;
|
||||||
|
backward = false;
|
||||||
|
left = false;
|
||||||
|
right = false;
|
||||||
|
jumping = false;
|
||||||
|
crouching = false;
|
||||||
|
sprinting = false;
|
||||||
|
hitting = false;
|
||||||
|
interacting = false;
|
||||||
|
reloading = false;
|
||||||
|
updateInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setForward(boolean forward) {
|
||||||
|
this.forward = forward;
|
||||||
|
updateInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackward(boolean backward) {
|
||||||
|
this.backward = backward;
|
||||||
|
updateInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeft(boolean left) {
|
||||||
|
this.left = left;
|
||||||
|
updateInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRight(boolean right) {
|
||||||
|
this.right = right;
|
||||||
|
updateInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJumping(boolean jumping) {
|
||||||
|
this.jumping = jumping;
|
||||||
|
updateInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCrouching(boolean crouching) {
|
||||||
|
this.crouching = crouching;
|
||||||
|
updateInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSprinting(boolean sprinting) {
|
||||||
|
this.sprinting = sprinting;
|
||||||
|
updateInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHitting(boolean hitting) {
|
||||||
|
this.hitting = hitting;
|
||||||
|
updateInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInteracting(boolean interacting) {
|
||||||
|
this.interacting = interacting;
|
||||||
|
updateInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReloading(boolean reloading) {
|
||||||
|
this.reloading = reloading;
|
||||||
|
updateInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelectedInventoryIndex(int selectedInventoryIndex) {
|
||||||
|
this.selectedInventoryIndex = selectedInventoryIndex;
|
||||||
|
updateInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toggleDebugEnabled() {
|
||||||
|
this.debugEnabled = !debugEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enableChatting() {
|
||||||
|
inputHandler.switchToChattingContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
resetInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
resetInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPress(long window, int key, int mods) {
|
||||||
|
switch (key) {
|
||||||
|
case GLFW_KEY_W -> setForward(true);
|
||||||
|
case GLFW_KEY_A -> setLeft(true);
|
||||||
|
case GLFW_KEY_S -> setBackward(true);
|
||||||
|
case GLFW_KEY_D -> setRight(true);
|
||||||
|
case GLFW_KEY_SPACE -> setJumping(true);
|
||||||
|
case GLFW_KEY_LEFT_CONTROL -> setCrouching(true);
|
||||||
|
case GLFW_KEY_LEFT_SHIFT -> setSprinting(true);
|
||||||
|
case GLFW_KEY_R -> setReloading(true);
|
||||||
|
|
||||||
|
case GLFW_KEY_1 -> setSelectedInventoryIndex(0);
|
||||||
|
case GLFW_KEY_2 -> setSelectedInventoryIndex(1);
|
||||||
|
case GLFW_KEY_3 -> setSelectedInventoryIndex(2);
|
||||||
|
case GLFW_KEY_4 -> setSelectedInventoryIndex(3);
|
||||||
|
|
||||||
|
case GLFW_KEY_F3 -> toggleDebugEnabled();
|
||||||
|
case GLFW_KEY_ESCAPE -> inputHandler.switchToExitMenuContext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyRelease(long window, int key, int mods) {
|
||||||
|
switch (key) {
|
||||||
|
case GLFW_KEY_W -> setForward(false);
|
||||||
|
case GLFW_KEY_A -> setLeft(false);
|
||||||
|
case GLFW_KEY_S -> setBackward(false);
|
||||||
|
case GLFW_KEY_D -> setRight(false);
|
||||||
|
case GLFW_KEY_SPACE -> setJumping(false);
|
||||||
|
case GLFW_KEY_LEFT_CONTROL -> setCrouching(false);
|
||||||
|
case GLFW_KEY_LEFT_SHIFT -> setSprinting(false);
|
||||||
|
case GLFW_KEY_R -> setReloading(false);
|
||||||
|
|
||||||
|
case GLFW_KEY_T -> enableChatting();
|
||||||
|
case GLFW_KEY_SLASH -> {
|
||||||
|
enableChatting();
|
||||||
|
inputHandler.getChattingContext().appendToChat("/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseButtonPress(long window, int button, int mods) {
|
||||||
|
switch (button) {
|
||||||
|
case GLFW_MOUSE_BUTTON_1 -> setHitting(true);
|
||||||
|
case GLFW_MOUSE_BUTTON_2 -> setInteracting(true);
|
||||||
|
case GLFW_MOUSE_BUTTON_3 -> pickBlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseButtonRelease(long window, int button, int mods) {
|
||||||
|
switch (button) {
|
||||||
|
case GLFW_MOUSE_BUTTON_1 -> setHitting(false);
|
||||||
|
case GLFW_MOUSE_BUTTON_2 -> setInteracting(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseScroll(long window, double xOffset, double yOffset) {
|
||||||
|
var player = inputHandler.getClient().getMyPlayer();
|
||||||
|
ItemStack stack = player.getInventory().getSelectedItemStack();
|
||||||
|
if (stack instanceof BlockItemStack blockStack) {
|
||||||
|
if (yOffset < 0) {
|
||||||
|
blockStack.setSelectedValue((byte) (blockStack.getSelectedValue() - 1));
|
||||||
|
} else if (yOffset > 0) {
|
||||||
|
blockStack.setSelectedValue((byte) (blockStack.getSelectedValue() + 1));
|
||||||
|
}
|
||||||
|
inputHandler.getComm().sendDatagramPacket(new BlockColorMessage(player.getId(), blockStack.getSelectedValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseCursorPos(long window, double xPos, double yPos) {
|
||||||
|
double[] xb = new double[1];
|
||||||
|
double[] yb = new double[1];
|
||||||
|
glfwGetCursorPos(window, xb, yb);
|
||||||
|
float x = (float) xb[0];
|
||||||
|
float y = (float) yb[0];
|
||||||
|
float dx = x - lastMouseCursorX;
|
||||||
|
float dy = y - lastMouseCursorY;
|
||||||
|
lastMouseCursorX = x;
|
||||||
|
lastMouseCursorY = y;
|
||||||
|
var client = inputHandler.getClient();
|
||||||
|
float trueSensitivity = inputHandler.getClient().getConfig().input.mouseSensitivity;
|
||||||
|
if (isScopeEnabled()) trueSensitivity *= 0.1f;
|
||||||
|
client.getMyPlayer().setOrientation(
|
||||||
|
client.getMyPlayer().getOrientation().x - dx * trueSensitivity,
|
||||||
|
client.getMyPlayer().getOrientation().y - dy * trueSensitivity
|
||||||
|
);
|
||||||
|
camera.setOrientationToPlayer(client.getMyPlayer());
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
if (lastOrientationUpdateSentAt + ORIENTATION_UPDATE_LIMIT < now) {
|
||||||
|
ForkJoinPool.commonPool().submit(() -> inputHandler.getComm().sendDatagramPacket(ClientOrientationState.fromPlayer(client.getMyPlayer())));
|
||||||
|
lastOrientationUpdateSentAt = now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pickBlock() {
|
||||||
|
var client = inputHandler.getClient();
|
||||||
|
var comm = inputHandler.getComm();
|
||||||
|
var player = client.getMyPlayer();
|
||||||
|
if (player.getInventory().getSelectedItemStack() instanceof BlockItemStack stack) {
|
||||||
|
Hit hit = client.getWorld().getLookingAtPos(player.getEyePosition(), player.getViewVector(), 50);
|
||||||
|
if (hit != null) {
|
||||||
|
byte selectedBlock = client.getWorld().getBlockAt(hit.pos().x, hit.pos().y, hit.pos().z);
|
||||||
|
if (selectedBlock > 0) {
|
||||||
|
stack.setSelectedValue(selectedBlock);
|
||||||
|
comm.sendDatagramPacket(new BlockColorMessage(player.getId(), selectedBlock));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isScopeEnabled() {
|
||||||
|
return interacting &&
|
||||||
|
inputHandler.getClient().getMyPlayer().getInventory().getSelectedItemStack() instanceof GunItemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDebugEnabled() {
|
||||||
|
return debugEnabled;
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,7 +48,7 @@ public class ClientPlayer extends Player {
|
||||||
.translate(cam.getPosition())
|
.translate(cam.getPosition())
|
||||||
.rotate((float) (cam.getOrientation().x + Math.PI), Camera.UP)
|
.rotate((float) (cam.getOrientation().x + Math.PI), Camera.UP)
|
||||||
.rotate(-cam.getOrientation().y + (float) Math.PI / 2, Camera.RIGHT);
|
.rotate(-cam.getOrientation().y + (float) Math.PI / 2, Camera.RIGHT);
|
||||||
if (inputHandler.isScopeEnabled()) {
|
if (inputHandler.isNormalContextActive() && inputHandler.getNormalContext().isScopeEnabled()) {
|
||||||
heldItemTransform.translate(0, -0.12f, 0);
|
heldItemTransform.translate(0, -0.12f, 0);
|
||||||
} else {
|
} else {
|
||||||
heldItemTransform.translate(-0.35f, -0.4f, 0.5f);
|
heldItemTransform.translate(-0.35f, -0.4f, 0.5f);
|
||||||
|
|
|
@ -39,6 +39,7 @@ public class GameRenderer {
|
||||||
private final ModelRenderer modelRenderer;
|
private final ModelRenderer modelRenderer;
|
||||||
private final Camera camera;
|
private final Camera camera;
|
||||||
private final Client client;
|
private final Client client;
|
||||||
|
private final InputHandler inputHandler;
|
||||||
|
|
||||||
// Standard models for various game components.
|
// Standard models for various game components.
|
||||||
private final Model playerModel;
|
private final Model playerModel;
|
||||||
|
@ -56,10 +57,11 @@ public class GameRenderer {
|
||||||
private final Matrix4f perspectiveTransform;
|
private final Matrix4f perspectiveTransform;
|
||||||
private final float[] perspectiveTransformData = new float[16];
|
private final float[] perspectiveTransformData = new float[16];
|
||||||
|
|
||||||
public GameRenderer(Client client, InputHandler inputHandler) {
|
public GameRenderer(Client client, InputHandler inputHandler, Camera camera) {
|
||||||
this.config = client.getConfig().display;
|
this.config = client.getConfig().display;
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.camera = new Camera();
|
this.inputHandler = inputHandler;
|
||||||
|
this.camera = camera;
|
||||||
camera.setToPlayer(client.getMyPlayer());
|
camera.setToPlayer(client.getMyPlayer());
|
||||||
this.perspectiveTransform = new Matrix4f();
|
this.perspectiveTransform = new Matrix4f();
|
||||||
|
|
||||||
|
@ -88,9 +90,9 @@ public class GameRenderer {
|
||||||
|
|
||||||
// Setup callbacks.
|
// Setup callbacks.
|
||||||
glfwSetKeyCallback(windowHandle, new PlayerInputKeyCallback(inputHandler));
|
glfwSetKeyCallback(windowHandle, new PlayerInputKeyCallback(inputHandler));
|
||||||
glfwSetCursorPosCallback(windowHandle, new PlayerViewCursorCallback(client, camera));
|
glfwSetCursorPosCallback(windowHandle, new PlayerViewCursorCallback(inputHandler));
|
||||||
glfwSetMouseButtonCallback(windowHandle, new PlayerInputMouseClickCallback(inputHandler));
|
glfwSetMouseButtonCallback(windowHandle, new PlayerInputMouseClickCallback(inputHandler));
|
||||||
glfwSetScrollCallback(windowHandle, new PlayerInputMouseScrollCallback(client));
|
glfwSetScrollCallback(windowHandle, new PlayerInputMouseScrollCallback(inputHandler));
|
||||||
glfwSetCharCallback(windowHandle, new PlayerCharacterInputCallback(inputHandler));
|
glfwSetCharCallback(windowHandle, new PlayerCharacterInputCallback(inputHandler));
|
||||||
if (config.captureCursor) {
|
if (config.captureCursor) {
|
||||||
glfwSetInputMode(windowHandle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
glfwSetInputMode(windowHandle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||||
|
@ -168,7 +170,7 @@ public class GameRenderer {
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
ClientPlayer myPlayer = client.getMyPlayer();
|
ClientPlayer myPlayer = client.getMyPlayer();
|
||||||
if (client.getInputHandler().isScopeEnabled()) {
|
if (inputHandler.isNormalContextActive() && inputHandler.getNormalContext().isScopeEnabled()) {
|
||||||
updatePerspective(15);
|
updatePerspective(15);
|
||||||
} else {
|
} else {
|
||||||
updatePerspective(config.fov);
|
updatePerspective(config.fov);
|
||||||
|
|
|
@ -2,7 +2,6 @@ package nl.andrewl.aos2_client.render.gui;
|
||||||
|
|
||||||
import nl.andrewl.aos2_client.Camera;
|
import nl.andrewl.aos2_client.Camera;
|
||||||
import nl.andrewl.aos2_client.Client;
|
import nl.andrewl.aos2_client.Client;
|
||||||
import nl.andrewl.aos2_client.model.Chat;
|
|
||||||
import nl.andrewl.aos2_client.model.ClientPlayer;
|
import nl.andrewl.aos2_client.model.ClientPlayer;
|
||||||
import nl.andrewl.aos2_client.model.OtherPlayer;
|
import nl.andrewl.aos2_client.model.OtherPlayer;
|
||||||
import nl.andrewl.aos2_client.render.ShaderProgram;
|
import nl.andrewl.aos2_client.render.ShaderProgram;
|
||||||
|
@ -223,15 +222,19 @@ public class GuiRenderer {
|
||||||
nvgBeginFrame(vgId, width, height, width / height);
|
nvgBeginFrame(vgId, width, height, width / height);
|
||||||
nvgSave(vgId);
|
nvgSave(vgId);
|
||||||
|
|
||||||
drawCrosshair(width, height, client.getInputHandler().isScopeEnabled());
|
boolean scopeEnabled = client.getInputHandler().getNormalContext().isScopeEnabled();
|
||||||
|
drawCrosshair(width, height, scopeEnabled);
|
||||||
drawHeldItemStackInfo(width, height, client.getMyPlayer());
|
drawHeldItemStackInfo(width, height, client.getMyPlayer());
|
||||||
if (!client.getInputHandler().isScopeEnabled()) {
|
if (!scopeEnabled) {
|
||||||
drawChat(width, height, client);
|
drawChat(width, height, client);
|
||||||
drawHealthBar(width, height, client.getMyPlayer());
|
drawHealthBar(width, height, client.getMyPlayer());
|
||||||
}
|
}
|
||||||
if (client.getInputHandler().isDebugEnabled()) {
|
if (client.getInputHandler().getNormalContext().isDebugEnabled()) {
|
||||||
drawDebugInfo(width, height, client);
|
drawDebugInfo(width, height, client);
|
||||||
}
|
}
|
||||||
|
if (client.getInputHandler().isExitMenuContextActive()) {
|
||||||
|
drawExitMenu(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
nvgRestore(vgId);
|
nvgRestore(vgId);
|
||||||
nvgEndFrame(vgId);
|
nvgEndFrame(vgId);
|
||||||
|
@ -353,13 +356,13 @@ public class GuiRenderer {
|
||||||
y -= 16;
|
y -= 16;
|
||||||
}
|
}
|
||||||
var input = client.getInputHandler();
|
var input = client.getInputHandler();
|
||||||
if (input.isChatting()) {
|
if (input.isChattingContextActive()) {
|
||||||
nvgFillColor(vgId, GuiUtils.rgba(0, 0, 0, 0.5f, colorA));
|
nvgFillColor(vgId, GuiUtils.rgba(0, 0, 0, 0.5f, colorA));
|
||||||
nvgBeginPath(vgId);
|
nvgBeginPath(vgId);
|
||||||
nvgRect(vgId, 0, h - 16, w, 16);
|
nvgRect(vgId, 0, h - 16, w, 16);
|
||||||
nvgFill(vgId);
|
nvgFill(vgId);
|
||||||
nvgFillColor(vgId, GuiUtils.rgba(1, 1, 1, 1, colorA));
|
nvgFillColor(vgId, GuiUtils.rgba(1, 1, 1, 1, colorA));
|
||||||
nvgText(vgId, 5, h - 14, "> " + input.getChatText() + "_");
|
nvgText(vgId, 5, h - 14, "> " + input.getChattingContext().getChatBufferText() + "_");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,4 +397,17 @@ public class GuiRenderer {
|
||||||
nvgText(vgId, 5, y, String.format("Looking at: x=%d, y=%d, z=%d", hit.pos().x, hit.pos().y, hit.pos().z));
|
nvgText(vgId, 5, y, String.format("Looking at: x=%d, y=%d, z=%d", hit.pos().x, hit.pos().y, hit.pos().z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void drawExitMenu(float width, float height) {
|
||||||
|
nvgFillColor(vgId, GuiUtils.rgba(0, 0, 0, 0.5f, colorA));
|
||||||
|
nvgBeginPath(vgId);
|
||||||
|
nvgRect(vgId, 0, 0, width, height);
|
||||||
|
nvgFill(vgId);
|
||||||
|
|
||||||
|
nvgFontSize(vgId, 12f);
|
||||||
|
nvgFontFaceId(vgId, jetbrainsMonoFont);
|
||||||
|
nvgTextAlign(vgId, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
|
||||||
|
nvgFillColor(vgId, GuiUtils.rgba(1, 1, 1, 1, colorA));
|
||||||
|
nvgText(vgId, width / 2f, height / 2f, "Press ESC to quit. Press any other key to return to the game.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package nl.andrewl.aos2_client.util;
|
||||||
|
|
||||||
|
import nl.andrewl.aos_core.Pair;
|
||||||
|
import org.lwjgl.BufferUtils;
|
||||||
|
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
|
||||||
|
import static org.lwjgl.glfw.GLFW.*;
|
||||||
|
|
||||||
|
public class WindowUtils {
|
||||||
|
public static Pair<Integer, Integer> getSize(long id) {
|
||||||
|
IntBuffer wBuf = BufferUtils.createIntBuffer(1);
|
||||||
|
IntBuffer hBuf = BufferUtils.createIntBuffer(1);
|
||||||
|
glfwGetWindowSize(id, wBuf, hBuf);
|
||||||
|
return new Pair<>(wBuf.get(0), hBuf.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void captureCursor(long id) {
|
||||||
|
glfwSetInputMode(id, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void freeCursor(long id) {
|
||||||
|
glfwSetInputMode(id, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||||
|
var size = WindowUtils.getSize(id);
|
||||||
|
glfwSetCursorPos(id, size.first() / 2.0, size.second() / 2.0);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue