Added scope mechanism to the game!
This commit is contained in:
parent
4f172ccb98
commit
dbdfcc554b
|
@ -4,13 +4,12 @@ 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.model.ClientPlayer;
|
||||||
import nl.andrewl.aos_core.model.item.BlockItemStack;
|
import nl.andrewl.aos_core.model.item.BlockItemStack;
|
||||||
|
import nl.andrewl.aos_core.model.item.GunItemStack;
|
||||||
import nl.andrewl.aos_core.model.world.Hit;
|
import nl.andrewl.aos_core.model.world.Hit;
|
||||||
import nl.andrewl.aos_core.net.client.BlockColorMessage;
|
import nl.andrewl.aos_core.net.client.BlockColorMessage;
|
||||||
import nl.andrewl.aos_core.net.client.ChatWrittenMessage;
|
import nl.andrewl.aos_core.net.client.ChatWrittenMessage;
|
||||||
import nl.andrewl.aos_core.net.client.ClientInputState;
|
import nl.andrewl.aos_core.net.client.ClientInputState;
|
||||||
|
|
||||||
import static org.lwjgl.glfw.GLFW.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
|
@ -234,6 +233,11 @@ public class InputHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isScopeEnabled() {
|
||||||
|
return interacting &&
|
||||||
|
client.getMyPlayer().getInventory().getSelectedItemStack() instanceof GunItemStack;
|
||||||
|
}
|
||||||
|
|
||||||
public void pickBlock() {
|
public void pickBlock() {
|
||||||
var player = client.getMyPlayer();
|
var player = client.getMyPlayer();
|
||||||
if (player.getInventory().getSelectedItemStack() instanceof BlockItemStack stack) {
|
if (player.getInventory().getSelectedItemStack() instanceof BlockItemStack stack) {
|
||||||
|
|
|
@ -48,9 +48,11 @@ public class PlayerViewCursorCallback implements GLFWCursorPosCallbackI {
|
||||||
float dy = y - lastMouseCursorY;
|
float dy = y - lastMouseCursorY;
|
||||||
lastMouseCursorX = x;
|
lastMouseCursorX = x;
|
||||||
lastMouseCursorY = y;
|
lastMouseCursorY = y;
|
||||||
|
float trueSensitivity = config.mouseSensitivity;
|
||||||
|
if (client.getInputHandler().isScopeEnabled()) trueSensitivity *= 0.1f;
|
||||||
client.getMyPlayer().setOrientation(
|
client.getMyPlayer().setOrientation(
|
||||||
client.getMyPlayer().getOrientation().x - dx * config.mouseSensitivity,
|
client.getMyPlayer().getOrientation().x - dx * trueSensitivity,
|
||||||
client.getMyPlayer().getOrientation().y - dy * config.mouseSensitivity
|
client.getMyPlayer().getOrientation().y - dy * trueSensitivity
|
||||||
);
|
);
|
||||||
camera.setOrientationToPlayer(client.getMyPlayer());
|
camera.setOrientationToPlayer(client.getMyPlayer());
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package nl.andrewl.aos2_client.model;
|
package nl.andrewl.aos2_client.model;
|
||||||
|
|
||||||
import nl.andrewl.aos2_client.Camera;
|
import nl.andrewl.aos2_client.Camera;
|
||||||
|
import nl.andrewl.aos2_client.control.InputHandler;
|
||||||
import nl.andrewl.aos_core.model.Player;
|
import nl.andrewl.aos_core.model.Player;
|
||||||
import nl.andrewl.aos_core.model.item.Inventory;
|
import nl.andrewl.aos_core.model.item.Inventory;
|
||||||
import org.joml.Matrix3f;
|
import org.joml.Matrix3f;
|
||||||
|
@ -42,12 +43,16 @@ public class ClientPlayer extends Player {
|
||||||
this.health = health;
|
this.health = health;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateHeldItemTransform(Camera cam) {
|
public void updateHeldItemTransform(Camera cam, InputHandler inputHandler) {
|
||||||
heldItemTransform.identity()
|
heldItemTransform.identity()
|
||||||
.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);
|
||||||
.translate(-0.35f, -0.4f, 0.5f);
|
if (inputHandler.isScopeEnabled()) {
|
||||||
|
heldItemTransform.translate(0, -0.12f, 0);
|
||||||
|
} else {
|
||||||
|
heldItemTransform.translate(-0.35f, -0.4f, 0.5f);
|
||||||
|
}
|
||||||
heldItemTransform.get(heldItemTransformData);
|
heldItemTransform.get(heldItemTransformData);
|
||||||
|
|
||||||
heldItemTransform.normal(heldItemNormalTransform);
|
heldItemTransform.normal(heldItemNormalTransform);
|
||||||
|
|
|
@ -56,6 +56,7 @@ public class GameRenderer {
|
||||||
private final int screenHeight;
|
private final int screenHeight;
|
||||||
|
|
||||||
private final Matrix4f perspectiveTransform;
|
private final Matrix4f perspectiveTransform;
|
||||||
|
private final float[] perspectiveTransformData = new float[16];
|
||||||
|
|
||||||
public GameRenderer(Client client, InputHandler inputHandler) {
|
public GameRenderer(Client client, InputHandler inputHandler) {
|
||||||
this.config = client.getConfig().display;
|
this.config = client.getConfig().display;
|
||||||
|
@ -155,10 +156,9 @@ public class GameRenderer {
|
||||||
fovRad = 0.01f;
|
fovRad = 0.01f;
|
||||||
}
|
}
|
||||||
perspectiveTransform.setPerspective(fovRad, getAspectRatio(), Z_NEAR, Z_FAR);
|
perspectiveTransform.setPerspective(fovRad, getAspectRatio(), Z_NEAR, Z_FAR);
|
||||||
float[] data = new float[16];
|
perspectiveTransform.get(perspectiveTransformData);
|
||||||
perspectiveTransform.get(data);
|
if (chunkRenderer != null) chunkRenderer.setPerspective(perspectiveTransformData);
|
||||||
if (chunkRenderer != null) chunkRenderer.setPerspective(data);
|
if (modelRenderer != null) modelRenderer.setPerspective(perspectiveTransformData);
|
||||||
if (modelRenderer != null) modelRenderer.setPerspective(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean windowShouldClose() {
|
public boolean windowShouldClose() {
|
||||||
|
@ -175,13 +175,19 @@ public class GameRenderer {
|
||||||
|
|
||||||
public void draw() {
|
public void draw() {
|
||||||
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);
|
||||||
chunkRenderer.draw(camera, client.getWorld().getChunkMeshesToDraw());
|
|
||||||
|
|
||||||
ClientPlayer myPlayer = client.getMyPlayer();
|
ClientPlayer myPlayer = client.getMyPlayer();
|
||||||
|
if (client.getInputHandler().isScopeEnabled()) {
|
||||||
|
updatePerspective(15);
|
||||||
|
} else {
|
||||||
|
updatePerspective(config.fov);
|
||||||
|
}
|
||||||
|
myPlayer.updateHeldItemTransform(camera, client.getInputHandler());
|
||||||
|
|
||||||
|
chunkRenderer.draw(camera, client.getWorld().getChunkMeshesToDraw());
|
||||||
|
|
||||||
// Draw models. Use one texture at a time for efficiency.
|
// Draw models. Use one texture at a time for efficiency.
|
||||||
modelRenderer.start(camera.getViewTransformData());
|
modelRenderer.start(camera.getViewTransformData());
|
||||||
myPlayer.updateHeldItemTransform(camera);
|
|
||||||
|
|
||||||
playerModel.bind();
|
playerModel.bind();
|
||||||
for (var player : client.getPlayers().values()) {
|
for (var player : client.getPlayers().values()) {
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package nl.andrewl.aos2_client.render;
|
||||||
|
|
||||||
|
public record TransformData(
|
||||||
|
float[] tx,
|
||||||
|
float[] norm
|
||||||
|
) {}
|
|
@ -222,10 +222,12 @@ public class GuiRenderer {
|
||||||
nvgBeginFrame(vgId, width, height, width / height);
|
nvgBeginFrame(vgId, width, height, width / height);
|
||||||
nvgSave(vgId);
|
nvgSave(vgId);
|
||||||
|
|
||||||
drawCrosshair(width, height);
|
drawCrosshair(width, height, client.getInputHandler().isScopeEnabled());
|
||||||
|
if (!client.getInputHandler().isScopeEnabled()) {
|
||||||
drawChat(width, height, client);
|
drawChat(width, height, client);
|
||||||
drawHealthBar(width, height, client.getMyPlayer());
|
drawHealthBar(width, height, client.getMyPlayer());
|
||||||
drawHeldItemStackInfo(width, height, client.getMyPlayer());
|
drawHeldItemStackInfo(width, height, client.getMyPlayer());
|
||||||
|
}
|
||||||
if (client.getInputHandler().isDebugEnabled()) {
|
if (client.getInputHandler().isDebugEnabled()) {
|
||||||
drawDebugInfo(width, height, client);
|
drawDebugInfo(width, height, client);
|
||||||
}
|
}
|
||||||
|
@ -253,16 +255,18 @@ public class GuiRenderer {
|
||||||
shaderProgram.free();
|
shaderProgram.free();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawCrosshair(float w, float h) {
|
private void drawCrosshair(float w, float h, boolean scopeEnabled) {
|
||||||
float cx = w / 2f;
|
float cx = w / 2f;
|
||||||
float cy = h / 2f;
|
float cy = h / 2f;
|
||||||
|
float size = 20f;
|
||||||
|
if (scopeEnabled) size = 3f;
|
||||||
|
|
||||||
nvgStrokeColor(vgId, GuiUtils.rgba(1, 1, 1, 0.25f, colorA));
|
nvgStrokeColor(vgId, GuiUtils.rgba(1, 1, 1, 0.25f, colorA));
|
||||||
nvgBeginPath(vgId);
|
nvgBeginPath(vgId);
|
||||||
nvgMoveTo(vgId, cx - 10, cy);
|
nvgMoveTo(vgId, cx - size / 2, cy);
|
||||||
nvgLineTo(vgId, cx + 10, cy);
|
nvgLineTo(vgId, cx + size / 2, cy);
|
||||||
nvgMoveTo(vgId, cx, cy - 10);
|
nvgMoveTo(vgId, cx, cy - size / 2);
|
||||||
nvgLineTo(vgId, cx, cy + 10);
|
nvgLineTo(vgId, cx, cy + size / 2);
|
||||||
nvgStroke(vgId);
|
nvgStroke(vgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,14 +54,22 @@ public class ProjectileManager {
|
||||||
if (nextProjectileId == Integer.MAX_VALUE) nextProjectileId = 1;
|
if (nextProjectileId == Integer.MAX_VALUE) nextProjectileId = 1;
|
||||||
|
|
||||||
pos.set(0);
|
pos.set(0);
|
||||||
|
direction.set(player.getViewVector()).normalize();
|
||||||
|
float accuracy = gun.getAccuracy();
|
||||||
|
|
||||||
|
if (player.getActionManager().isScopeEnabled()) {
|
||||||
|
bulletTransform.identity()
|
||||||
|
.translate(player.getEyePosition())
|
||||||
|
.rotate(player.getOrientation().x + (float) Math.PI, Directions.UPf);
|
||||||
|
accuracy += (1f - accuracy) / 2f;
|
||||||
|
} else {
|
||||||
bulletTransform.identity()
|
bulletTransform.identity()
|
||||||
.translate(player.getEyePosition())
|
.translate(player.getEyePosition())
|
||||||
.rotate(player.getOrientation().x + (float) Math.PI, Directions.UPf)
|
.rotate(player.getOrientation().x + (float) Math.PI, Directions.UPf)
|
||||||
.translate(-0.35f, -0.4f, 0.35f);
|
.translate(-0.35f, -0.4f, 0.35f);
|
||||||
bulletTransform.transformPosition(pos);
|
}
|
||||||
|
|
||||||
direction.set(player.getViewVector()).normalize();
|
bulletTransform.transformPosition(pos);
|
||||||
float accuracy = gun.getAccuracy();
|
|
||||||
accuracy -= server.getConfig().actions.movementAccuracyDecreaseFactor * player.getVelocity().length();
|
accuracy -= server.getConfig().actions.movementAccuracyDecreaseFactor * player.getVelocity().length();
|
||||||
float perturbationFactor = (1 - accuracy) / 8;
|
float perturbationFactor = (1 - accuracy) / 8;
|
||||||
direction.x += rand.nextGaussian(0, perturbationFactor);
|
direction.x += rand.nextGaussian(0, perturbationFactor);
|
||||||
|
|
|
@ -56,6 +56,11 @@ public class PlayerActionManager {
|
||||||
return input.setLastInputState(lastInputState);
|
return input.setLastInputState(lastInputState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isScopeEnabled() {
|
||||||
|
return input.interacting() &&
|
||||||
|
player.getInventory().getSelectedItemStack() instanceof GunItemStack;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isUpdated() {
|
public boolean isUpdated() {
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
@ -113,6 +118,7 @@ public class PlayerActionManager {
|
||||||
server.getPlayerManager().getHandler(player.getId()).sendDatagramPacket(new ItemStackMessage(player.getInventory()));
|
server.getPlayerManager().getHandler(player.getId()).sendDatagramPacket(new ItemStackMessage(player.getInventory()));
|
||||||
// Apply recoil!
|
// Apply recoil!
|
||||||
float recoilFactor = 10f; // Maximum number of degrees to recoil.
|
float recoilFactor = 10f; // Maximum number of degrees to recoil.
|
||||||
|
if (isScopeEnabled()) recoilFactor *= 0.1f;
|
||||||
float recoil = recoilFactor * gun.getRecoil() + (float) ThreadLocalRandom.current().nextGaussian(0, 0.01);
|
float recoil = recoilFactor * gun.getRecoil() + (float) ThreadLocalRandom.current().nextGaussian(0, 0.01);
|
||||||
server.getPlayerManager().getHandler(player.getId()).sendDatagramPacket(new ClientRecoilMessage(0, Math.toRadians(recoil)));
|
server.getPlayerManager().getHandler(player.getId()).sendDatagramPacket(new ClientRecoilMessage(0, Math.toRadians(recoil)));
|
||||||
// Play sound!
|
// Play sound!
|
||||||
|
@ -249,7 +255,7 @@ public class PlayerActionManager {
|
||||||
acceleration.rotateAxis(orientation.x, 0, 1, 0);
|
acceleration.rotateAxis(orientation.x, 0, 1, 0);
|
||||||
acceleration.mul(config.movementAcceleration);
|
acceleration.mul(config.movementAcceleration);
|
||||||
horizontalVelocity.add(acceleration);
|
horizontalVelocity.add(acceleration);
|
||||||
final float maxSpeed;
|
float maxSpeed;
|
||||||
if (input.crouching()) {
|
if (input.crouching()) {
|
||||||
maxSpeed = config.crouchingSpeed;
|
maxSpeed = config.crouchingSpeed;
|
||||||
} else if (input.sprinting()) {
|
} else if (input.sprinting()) {
|
||||||
|
@ -257,6 +263,8 @@ public class PlayerActionManager {
|
||||||
} else {
|
} else {
|
||||||
maxSpeed = config.walkingSpeed;
|
maxSpeed = config.walkingSpeed;
|
||||||
}
|
}
|
||||||
|
// If scoping, then force limit to crouching speed.
|
||||||
|
if (isScopeEnabled()) maxSpeed = config.crouchingSpeed;
|
||||||
if (horizontalVelocity.length() > maxSpeed) {
|
if (horizontalVelocity.length() > maxSpeed) {
|
||||||
horizontalVelocity.normalize(maxSpeed);
|
horizontalVelocity.normalize(maxSpeed);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue