package org.jrenner.fps.input;
import com.badlogic.gdx.*;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.ObjectMap;
import org.jrenner.fps.Direction;
import org.jrenner.fps.Log;
import org.jrenner.fps.Main;
import org.jrenner.fps.Player;
import org.jrenner.fps.net.packages.CommandPackage;
import org.jrenner.fps.utils.Pooler;
import org.jrenner.fps.Toggleable;
import org.jrenner.fps.View;
import static com.badlogic.gdx.Input.Keys.*;
public class Input extends InputAdapter {
private boolean[] pressed = new boolean[256];
public ObjectMap<InputBind, Direction.Translation> transBindingMap = new ObjectMap<>();
public ObjectMap<InputBind, Direction.Rotation> rotBindingMap = new ObjectMap<>();
public Input() {
InputBind.setDefaultBindings();
transBindingMap.put(InputBind.MoveForward, Direction.Translation.Forward);
transBindingMap.put(InputBind.MoveBack, Direction.Translation.Back);
transBindingMap.put(InputBind.MoveLeft, Direction.Translation.Left);
transBindingMap.put(InputBind.MoveRight, Direction.Translation.Right);
transBindingMap.put(InputBind.MoveUp, Direction.Translation.Up);
transBindingMap.put(InputBind.MoveDown, Direction.Translation.Down);
rotBindingMap.put(InputBind.YawLeft, Direction.Rotation.YawLeft);
rotBindingMap.put(InputBind.YawRight, Direction.Rotation.YawRight);
rotBindingMap.put(InputBind.PitchUp, Direction.Rotation.PitchUp);
rotBindingMap.put(InputBind.PitchDown, Direction.Rotation.PitchDown);
}
public void process() {
if (Toggleable.controlPlayer()) {
// TODO update interval
playerControls();
} else {
cameraControls();
}
constrainMouse();
}
private void constrainMouse() {
int x = Gdx.input.getX();
int y = Gdx.input.getY();
if (x < 0 || x > View.width || y < 0 || y > View.height) {
lastScreenX = -1;
lastScreenY = -1;
Gdx.input.setCursorPosition(View.width / 2, View.height / 2);
}
}
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
//DynamicEntity.player.startShoot();
/*InputBind ib = InputBind.matchByMouse(button);
return true;*/
return false;
}
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
//DynamicEntity.player.stopShoot();
//return true;
return false;
}
@Override
public boolean keyDown(int keycode) {
if (View.inst.hud.isChatOpen()) {
openedChatKeyDown(keycode);
return true;
}
pressed[keycode] = true;
switch (keycode) {
case ESCAPE:
Toggleable.toggle(Toggleable.MOUSE_LOOK);
return true;
case T:
View.inst.hud.showChatField();
return true;
case P:
Main.pause = !Main.pause;
return true;
case F1:
Toggleable.toggle(Toggleable.DEBUG_DRAW);
return true;
case F2:
Toggleable.toggle(Toggleable.PROFILE_GL);
return true;
case F4:
Toggleable.toggle(Toggleable.CONTROL_PLAYER);
return true;
case C:
Toggleable.toggle(Toggleable.FREE_CAMERA);
return true;
}
return false;
}
private void openedChatKeyDown(int keycode) {
if (keycode == ESCAPE) {
View.inst.hud.hideChatField();
}
}
protected static final float moveStep = 0.1f;
protected static Vector3 tmp = new Vector3();
protected static Vector3 tmp2 = new Vector3();
@Override
public boolean keyUp(int keycode) {
pressed[keycode] = false;
return false;
}
private int lastScreenX = -1;
private int lastScreenY = -1;
@Override
public boolean mouseMoved(int screenX, int screenY) {
return mousePan(screenX, screenY);
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
if (Main.isDesktop()) {
return mousePan(screenX, screenY);
}
return false;
}
private boolean mousePan(int screenX, int screenY) {
if (!Toggleable.mouseLook()) return false;
if (lastScreenX < 0 || lastScreenY < 0) {
lastScreenX = screenX;
lastScreenY = screenY;
return true;
}
float sensitivity = 0.2f;
float yawDelta = 0.5f;
float pitchDelta = 0.5f;
float yaw = (screenX - lastScreenX) * yawDelta;
float pitch = (screenY - lastScreenY) * pitchDelta;
if (!Toggleable.controlPlayer()) {
if (yaw != 0) {
View.inst.rotateCamera(Direction.Rotation.YawRight, yaw * sensitivity);
}
if (pitch != 0) {
View.inst.rotateCamera(Direction.Rotation.YawLeft, -pitch * sensitivity);
}
} else {
Player player = Main.inst.client.player;
if (player != null) {
if (yaw != 0) {
player.entity.adjustYaw(-yaw);
}
if (pitch != 0) {
player.entity.adjustPitch(pitch);
}
}
}
lastScreenX = screenX;
lastScreenY = screenY;
return true;
}
public boolean isPressed(int code) {
if (code < 0) return false;
return pressed[code];
}
public boolean isShiftPressed() { return isPressed(SHIFT_LEFT) || isPressed(SHIFT_RIGHT); }
public boolean isCtrlPressed() { return isPressed(CONTROL_LEFT) || isPressed(CONTROL_RIGHT); }
// camera controls
private void cameraControls() {
float rotStep = 1f;
if (InputBind.YawLeft.isPressed()) {
View.inst.rotateCamera(Direction.Rotation.YawLeft, rotStep);
}
if (InputBind.YawRight.isPressed()) {
View.inst.rotateCamera(Direction.Rotation.YawRight, rotStep);
}
if (InputBind.PitchUp.isPressed()) {
View.inst.rotateCamera(Direction.Rotation.PitchUp, rotStep);
}
if (InputBind.PitchDown.isPressed()) {
View.inst.rotateCamera(Direction.Rotation.PitchDown, rotStep);
}
}
/** process player controls and send to server */
public void playerControls() {
/** this method will only be called on a client, it works in the following way:
* translation inputs are added to a vector
* if the vector is not zero, the player's entity has its relative destination set to the vector
* if this instance of the app is not a server (either NetServer or LocalServer)
* the CommandPackage is transmitted to the server
*/
Player player = Main.inst.client.player;
if (player == null) return;
CommandPackage cmdPack = Pooler.movementPackage();
tmp.setZero();
for (InputBind inputBind : transBindingMap.keys()) {
if (inputBind.isPressed()) {
Direction.Translation trans = transBindingMap.get(inputBind);
cmdPack.setTranslation(trans);
tmp.add(trans.vector);
}
}
if (Main.isMobile()) {
View.inst.hud.getMoveTranslation(tmp);
}
if (!tmp.isZero()) {
player.entity.setRelativeDestinationByYaw(tmp.nor().scl(0.1f));
} else {
player.entity.setDestination(null);
}
for (InputBind inputBind : rotBindingMap.keys()) {
if (inputBind.isPressed()) {
player.entity.adjustRotation(rotBindingMap.get(inputBind));
}
}
if (InputBind.Jump.isPressed()) {
cmdPack.set(CommandPackage.JUMP, true);
player.entity.jump();
}
boolean shooting = false;
boolean mobileShoot = Main.isMobile() && View.inst.hud.shoot.isPressed();
boolean desktopShoot = Main.isDesktop() && InputBind.Shoot.isPressed();
if (mobileShoot || desktopShoot) {
cmdPack.set(CommandPackage.SHOOT, true);
shooting = true;
}
if (Main.isServer()) {
if (shooting) {
player.entity.startShoot();
} else {
player.entity.stopShoot();
}
}
if (isPressed(com.badlogic.gdx.Input.Keys.R)) {
Main.inst.client.requestResetPosition();
}
cmdPack.setRotation(player.entity.getRotation());
if (!Main.isServer()) {
Main.getNetClient().sendClientUpdateToServer(cmdPack);
}
Pooler.free(cmdPack);
}
}