/*
* Aphelion
* Copyright (c) 2013 Joris van der Wel
*
* This file is part of Aphelion
*
* Aphelion is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* Aphelion is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Aphelion. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, the following supplemental terms apply, based on section 7 of
* the GNU Affero General Public License (version 3):
* a) Preservation of all legal notices and author attributions
* b) Prohibition of misrepresentation of the origin of this material, and
* modified versions are required to be marked in reasonable ways as
* different from the original version (for example by appending a copyright notice).
*
* Linking this library statically or dynamically with other modules is making a
* combined work based on this library. Thus, the terms and conditions of the
* GNU Affero General Public License cover the whole combination.
*
* As a special exception, the copyright holders of this library give you
* permission to link this library with independent modules to produce an
* executable, regardless of the license terms of these independent modules,
* and to copy and distribute the resulting executable under terms of your
* choice, provided that you also meet, for each linked independent module,
* the terms and conditions of the license of that module. An independent
* module is a module which is not derived from or based on this library.
*/
package aphelion.client;
import aphelion.client.net.NetworkedGame;
import aphelion.shared.event.TickEvent;
import aphelion.shared.gameconfig.GCStringList;
import aphelion.shared.physics.PhysicsEnvironment;
import aphelion.shared.physics.WEAPON_SLOT;
import aphelion.shared.physics.entities.ActorPublic;
import aphelion.shared.physics.valueobjects.PhysicsMovement;
import aphelion.shared.physics.valueobjects.PhysicsShipPosition;
import de.lessvoid.nifty.elements.Element;
import de.lessvoid.nifty.input.keyboard.KeyboardInputEvent;
import de.lessvoid.nifty.renderer.lwjgl.input.LwjglInputSystem;
import de.lessvoid.nifty.screen.Screen;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
import org.lwjgl.input.Keyboard;
/**
*
* @author Joris
*/
public class MyKeyboard implements TickEvent
{
private static final Logger log = Logger.getLogger("aphelion.client");
private final LwjglInputSystem input;
private final Screen mainScreen;
private final NetworkedGame networkedGame;
private final PhysicsEnvironment physicsEnv;
/** The actor this keyboard input is for */
private final ActorPublic controllingActor;
private final GCStringList ships;
private final Element gameMenuPopup;
private final Element bigRadar;
private final Element smallRadar;
private long tick;
// Key states:
private boolean up, down, left, right, boost;
private boolean multiFireGun;
private boolean fireGun;
private boolean fireBomb;
private boolean fireMine;
private boolean fireThor;
private boolean fireBurst;
private boolean fireRepel;
private boolean fireDecoy;
private boolean fireRocket;
private boolean fireBrick;
public MyKeyboard(@Nonnull LwjglInputSystem input,
@Nonnull Screen mainScreen,
@Nonnull NetworkedGame networkedGame,
@Nonnull PhysicsEnvironment physicsEnv,
@Nonnull ActorPublic controllingActor,
@Nonnull GCStringList ships,
@Nonnull Element gameMenuPopup)
{
this.input = input;
this.mainScreen = mainScreen;
this.networkedGame = networkedGame;
this.physicsEnv = physicsEnv;
this.controllingActor = controllingActor;
this.ships = ships;
this.gameMenuPopup = gameMenuPopup;
this.bigRadar = mainScreen.findElementByName("radar-big");
this.smallRadar = mainScreen.findElementByName("radar-small");
}
public boolean isMultiFireGun()
{
return multiFireGun;
}
public void poll()
{
// must come after nifty.update()
/*if (!Display.isActive())
{
up = false;
down = false;
left = false;
right = false;
boost = false;
fireGun = false;
fireBomb = false;
fireThor = false;
fireBurst = false;
fireRepel = false;
fireDecoy = false;
fireRocket = false;
fireBrick = false;
return;
}*/
boolean shift = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)
|| Keyboard.isKeyDown(Keyboard.KEY_RSHIFT);
/*boolean ctrl = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL)
|| Keyboard.isKeyDown(Keyboard.KEY_RCONTROL);*/
up = Keyboard.isKeyDown(Keyboard.KEY_UP);
down = Keyboard.isKeyDown(Keyboard.KEY_DOWN);
left = Keyboard.isKeyDown(Keyboard.KEY_LEFT);
right = Keyboard.isKeyDown(Keyboard.KEY_RIGHT);
boost = shift;
fireGun = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL);
fireBomb = Keyboard.isKeyDown(Keyboard.KEY_TAB);
fireMine = Keyboard.isKeyDown(Keyboard.KEY_RCONTROL);
fireThor = Keyboard.isKeyDown(Keyboard.KEY_F6);
fireBurst = Keyboard.isKeyDown(Keyboard.KEY_DELETE) && shift;
fireRepel = Keyboard.isKeyDown(Keyboard.KEY_LMENU);
fireDecoy = Keyboard.isKeyDown(Keyboard.KEY_F5);
fireRocket = Keyboard.isKeyDown(Keyboard.KEY_F3);
fireBrick = Keyboard.isKeyDown(Keyboard.KEY_F4);
// Unparsed nifty keys:
while (input.hasNextKeyboardEvent())
{
KeyboardInputEvent event = input.nextKeyboardEvent();
int key = event.getKey();
char chr = event.getCharacter();
if (key == KeyboardInputEvent.KEY_RMENU)
{
if (bigRadar != null && smallRadar != null)
{
if (event.isKeyDown())
{
smallRadar.hide();
bigRadar.show();
}
else
{
bigRadar.hide();
smallRadar.show();
}
}
}
if (key == KeyboardInputEvent.KEY_ESCAPE)
{
if (!event.isKeyDown() && gameMenuPopup != null)
{
gameMenuPopup.getNifty().showPopup(mainScreen, gameMenuPopup.getId(), null);
}
}
if (!event.isKeyDown()) // released a key
{
if (key == KeyboardInputEvent.KEY_DELETE)
{
multiFireGun = !multiFireGun;
}
}
}
}
@Override
public void tick(long tick)
{
this.tick = tick;
// PhysicsEnvironment should have ticked before this one.
int localPid;
if (!networkedGame.isReady())
{
// esc to cancel connecting?
return;
}
localPid = networkedGame.getMyPid();
if (controllingActor.isNonExistent())
{
return;
}
if (up || down || left || right)
{
boost = boost && (up || down);
// do not bother sending boost over the network if we can not use it
// (to prevent unnecessary timewarps)
boost = boost && controllingActor.canBoost();
PhysicsMovement move = PhysicsMovement.get(up, down, left, right, boost);
physicsEnv.actorMove(physicsEnv.getTick(), localPid, move);
networkedGame.sendMove(physicsEnv.getTick(), move);
}
if (fireGun) { tryWeapon(this.multiFireGun ? WEAPON_SLOT.GUN_MULTI : WEAPON_SLOT.GUN); }
if (fireBomb) { tryWeapon(WEAPON_SLOT.BOMB); }
if (fireMine) { tryWeapon(WEAPON_SLOT.MINE); }
if (fireThor) { tryWeapon(WEAPON_SLOT.THOR); }
if (fireBurst) { tryWeapon(WEAPON_SLOT.BURST); }
if (fireRepel) { tryWeapon(WEAPON_SLOT.REPEL); }
if (fireDecoy) { tryWeapon(WEAPON_SLOT.DECOY); }
if (fireRocket){ tryWeapon(WEAPON_SLOT.ROCKET); }
if (fireBrick) { tryWeapon(WEAPON_SLOT.BRICK); }
}
private void tryWeapon(@Nonnull WEAPON_SLOT weapon)
{
if (!controllingActor.canFireWeapon(weapon))
{
return;
}
PhysicsShipPosition weaponHint = new PhysicsShipPosition();
controllingActor.getPosition(weaponHint);
physicsEnv.actorWeapon(
physicsEnv.getTick(),
networkedGame.getMyPid(),
weapon,
true, weaponHint.x, weaponHint.y,
weaponHint.x_vel, weaponHint.y_vel,
weaponHint.rot_snapped);
networkedGame.sendActorWeapon(physicsEnv.getTick(), weapon, weaponHint);
}
}