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.model.ClientPlayer;
|
||||
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.net.client.BlockColorMessage;
|
||||
import nl.andrewl.aos_core.net.client.ChatWrittenMessage;
|
||||
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.
|
||||
*/
|
||||
|
@ -234,6 +233,11 @@ public class InputHandler {
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -48,9 +48,11 @@ public class PlayerViewCursorCallback implements GLFWCursorPosCallbackI {
|
|||
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 * config.mouseSensitivity,
|
||||
client.getMyPlayer().getOrientation().y - dy * config.mouseSensitivity
|
||||
client.getMyPlayer().getOrientation().x - dx * trueSensitivity,
|
||||
client.getMyPlayer().getOrientation().y - dy * trueSensitivity
|
||||
);
|
||||
camera.setOrientationToPlayer(client.getMyPlayer());
|
||||
long now = System.currentTimeMillis();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package nl.andrewl.aos2_client.model;
|
||||
|
||||
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.item.Inventory;
|
||||
import org.joml.Matrix3f;
|
||||
|
@ -42,12 +43,16 @@ public class ClientPlayer extends Player {
|
|||
this.health = health;
|
||||
}
|
||||
|
||||
public void updateHeldItemTransform(Camera cam) {
|
||||
public void updateHeldItemTransform(Camera cam, InputHandler inputHandler) {
|
||||
heldItemTransform.identity()
|
||||
.translate(cam.getPosition())
|
||||
.rotate((float) (cam.getOrientation().x + Math.PI), Camera.UP)
|
||||
.rotate(-cam.getOrientation().y + (float) Math.PI / 2, Camera.RIGHT)
|
||||
.translate(-0.35f, -0.4f, 0.5f);
|
||||
.rotate(-cam.getOrientation().y + (float) Math.PI / 2, Camera.RIGHT);
|
||||
if (inputHandler.isScopeEnabled()) {
|
||||
heldItemTransform.translate(0, -0.12f, 0);
|
||||
} else {
|
||||
heldItemTransform.translate(-0.35f, -0.4f, 0.5f);
|
||||
}
|
||||
heldItemTransform.get(heldItemTransformData);
|
||||
|
||||
heldItemTransform.normal(heldItemNormalTransform);
|
||||
|
|
|
@ -56,6 +56,7 @@ public class GameRenderer {
|
|||
private final int screenHeight;
|
||||
|
||||
private final Matrix4f perspectiveTransform;
|
||||
private final float[] perspectiveTransformData = new float[16];
|
||||
|
||||
public GameRenderer(Client client, InputHandler inputHandler) {
|
||||
this.config = client.getConfig().display;
|
||||
|
@ -155,10 +156,9 @@ public class GameRenderer {
|
|||
fovRad = 0.01f;
|
||||
}
|
||||
perspectiveTransform.setPerspective(fovRad, getAspectRatio(), Z_NEAR, Z_FAR);
|
||||
float[] data = new float[16];
|
||||
perspectiveTransform.get(data);
|
||||
if (chunkRenderer != null) chunkRenderer.setPerspective(data);
|
||||
if (modelRenderer != null) modelRenderer.setPerspective(data);
|
||||
perspectiveTransform.get(perspectiveTransformData);
|
||||
if (chunkRenderer != null) chunkRenderer.setPerspective(perspectiveTransformData);
|
||||
if (modelRenderer != null) modelRenderer.setPerspective(perspectiveTransformData);
|
||||
}
|
||||
|
||||
public boolean windowShouldClose() {
|
||||
|
@ -175,13 +175,19 @@ public class GameRenderer {
|
|||
|
||||
public void draw() {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
chunkRenderer.draw(camera, client.getWorld().getChunkMeshesToDraw());
|
||||
|
||||
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.
|
||||
modelRenderer.start(camera.getViewTransformData());
|
||||
myPlayer.updateHeldItemTransform(camera);
|
||||
|
||||
playerModel.bind();
|
||||
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);
|
||||
nvgSave(vgId);
|
||||
|
||||
drawCrosshair(width, height);
|
||||
drawCrosshair(width, height, client.getInputHandler().isScopeEnabled());
|
||||
if (!client.getInputHandler().isScopeEnabled()) {
|
||||
drawChat(width, height, client);
|
||||
drawHealthBar(width, height, client.getMyPlayer());
|
||||
drawHeldItemStackInfo(width, height, client.getMyPlayer());
|
||||
}
|
||||
if (client.getInputHandler().isDebugEnabled()) {
|
||||
drawDebugInfo(width, height, client);
|
||||
}
|
||||
|
@ -253,16 +255,18 @@ public class GuiRenderer {
|
|||
shaderProgram.free();
|
||||
}
|
||||
|
||||
private void drawCrosshair(float w, float h) {
|
||||
private void drawCrosshair(float w, float h, boolean scopeEnabled) {
|
||||
float cx = w / 2f;
|
||||
float cy = h / 2f;
|
||||
float size = 20f;
|
||||
if (scopeEnabled) size = 3f;
|
||||
|
||||
nvgStrokeColor(vgId, GuiUtils.rgba(1, 1, 1, 0.25f, colorA));
|
||||
nvgBeginPath(vgId);
|
||||
nvgMoveTo(vgId, cx - 10, cy);
|
||||
nvgLineTo(vgId, cx + 10, cy);
|
||||
nvgMoveTo(vgId, cx, cy - 10);
|
||||
nvgLineTo(vgId, cx, cy + 10);
|
||||
nvgMoveTo(vgId, cx - size / 2, cy);
|
||||
nvgLineTo(vgId, cx + size / 2, cy);
|
||||
nvgMoveTo(vgId, cx, cy - size / 2);
|
||||
nvgLineTo(vgId, cx, cy + size / 2);
|
||||
nvgStroke(vgId);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,14 +54,22 @@ public class ProjectileManager {
|
|||
if (nextProjectileId == Integer.MAX_VALUE) nextProjectileId = 1;
|
||||
|
||||
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()
|
||||
.translate(player.getEyePosition())
|
||||
.rotate(player.getOrientation().x + (float) Math.PI, Directions.UPf)
|
||||
.translate(-0.35f, -0.4f, 0.35f);
|
||||
bulletTransform.transformPosition(pos);
|
||||
}
|
||||
|
||||
direction.set(player.getViewVector()).normalize();
|
||||
float accuracy = gun.getAccuracy();
|
||||
bulletTransform.transformPosition(pos);
|
||||
accuracy -= server.getConfig().actions.movementAccuracyDecreaseFactor * player.getVelocity().length();
|
||||
float perturbationFactor = (1 - accuracy) / 8;
|
||||
direction.x += rand.nextGaussian(0, perturbationFactor);
|
||||
|
|
|
@ -56,6 +56,11 @@ public class PlayerActionManager {
|
|||
return input.setLastInputState(lastInputState);
|
||||
}
|
||||
|
||||
public boolean isScopeEnabled() {
|
||||
return input.interacting() &&
|
||||
player.getInventory().getSelectedItemStack() instanceof GunItemStack;
|
||||
}
|
||||
|
||||
public boolean isUpdated() {
|
||||
return updated;
|
||||
}
|
||||
|
@ -113,6 +118,7 @@ public class PlayerActionManager {
|
|||
server.getPlayerManager().getHandler(player.getId()).sendDatagramPacket(new ItemStackMessage(player.getInventory()));
|
||||
// Apply 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);
|
||||
server.getPlayerManager().getHandler(player.getId()).sendDatagramPacket(new ClientRecoilMessage(0, Math.toRadians(recoil)));
|
||||
// Play sound!
|
||||
|
@ -249,7 +255,7 @@ public class PlayerActionManager {
|
|||
acceleration.rotateAxis(orientation.x, 0, 1, 0);
|
||||
acceleration.mul(config.movementAcceleration);
|
||||
horizontalVelocity.add(acceleration);
|
||||
final float maxSpeed;
|
||||
float maxSpeed;
|
||||
if (input.crouching()) {
|
||||
maxSpeed = config.crouchingSpeed;
|
||||
} else if (input.sprinting()) {
|
||||
|
@ -257,6 +263,8 @@ public class PlayerActionManager {
|
|||
} else {
|
||||
maxSpeed = config.walkingSpeed;
|
||||
}
|
||||
// If scoping, then force limit to crouching speed.
|
||||
if (isScopeEnabled()) maxSpeed = config.crouchingSpeed;
|
||||
if (horizontalVelocity.length() > maxSpeed) {
|
||||
horizontalVelocity.normalize(maxSpeed);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue