package com.jmrapp.terralegion.game.views.ui;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.viewport.StretchViewport;
import com.jmrapp.terralegion.engine.camera.OrthoCamera;
import com.jmrapp.terralegion.engine.input.InputController;
import com.jmrapp.terralegion.engine.input.JoystickControl;
import com.jmrapp.terralegion.engine.utils.Settings;
import com.jmrapp.terralegion.engine.utils.Timer;
import com.jmrapp.terralegion.engine.views.drawables.Drawable;
import com.jmrapp.terralegion.engine.views.drawables.ResourceManager;
import com.jmrapp.terralegion.engine.views.drawables.ui.PictureButton;
import com.jmrapp.terralegion.engine.views.screens.ScreenManager;
import com.jmrapp.terralegion.game.item.ItemStack;
import com.jmrapp.terralegion.game.item.impl.BlockItem;
import com.jmrapp.terralegion.game.item.impl.CombatItem;
import com.jmrapp.terralegion.game.item.impl.ToolItem;
import com.jmrapp.terralegion.game.item.impl.UsableItem;
import com.jmrapp.terralegion.game.utils.Vector2Factory;
import com.jmrapp.terralegion.game.views.screen.GameScreen;
import com.jmrapp.terralegion.game.views.screen.InventoryScreen;
import com.jmrapp.terralegion.game.world.DayManager;
import com.jmrapp.terralegion.game.world.World;
import com.jmrapp.terralegion.game.world.block.BlockManager;
import com.jmrapp.terralegion.game.world.block.BlockType;
import com.jmrapp.terralegion.game.world.chunk.Chunk;
import com.jmrapp.terralegion.game.world.chunk.ChunkManager;
import com.jmrapp.terralegion.game.world.entity.LivingEntity;
/**
* Created by Jon on 9/29/15.
*/
public class GameHud {
private static final Drawable blankTile = ResourceManager.getInstance().getDrawable("blankTile");
private static final Texture heartTexture = ResourceManager.getInstance().getTexture("heart");
private JoystickControl moveControl, actionControl;
private Stage stage;
private SpriteBatch stageSb, sb;
private OrthoCamera camera;
private World world;
private Texture bg;
private InventoryBox[] inventoryBoxes = new InventoryBox[5];
private PictureButton inventoryBtn = new PictureButton(ResourceManager.getInstance().getDrawable("inventoryBtn"), 20 + (InventoryBox.bg.getWidth() + 7) * 5, Settings.getHeight() - InventoryBox.bg.getHeight() - 10);
private float lastBlockPlace;
private Vector2 highlightedBlockPosition = Vector2Factory.instance.getVector2();
private Rectangle collisionTestRect = new Rectangle();
private GameScreen gameScreen;
public GameHud(GameScreen gameScreen, World world) {
this.gameScreen = gameScreen;
this.world = world;
stageSb = new SpriteBatch();
sb = new SpriteBatch();
stage = new Stage(new StretchViewport(Settings.getWidth(), Settings.getHeight()), stageSb);
moveControl = new JoystickControl(ResourceManager.getInstance().getTexture("joystickBg"), ResourceManager.getInstance().getTexture("joystickKnob"), 10, 20, 20, 200, 200);
actionControl = new JoystickControl(ResourceManager.getInstance().getTexture("joystickBg"), ResourceManager.getInstance().getTexture("joystickKnob"), 10, 550, 20, 200, 200);
stage.addActor(moveControl.getTouchpad());
stage.addActor(actionControl.getTouchpad());
stage.act(Gdx.graphics.getDeltaTime());
camera = new OrthoCamera();
InputController.getInstance().addInputProcessor(stage);
bg = ResourceManager.getInstance().getTexture("bg");
for (int i = 0; i < inventoryBoxes.length; i++) {
inventoryBoxes[i] = new InventoryBox(world.getPlayer().getInventory().getItemStack(i, 0), 20 + (i * (InventoryBox.bg.getWidth() + 7)), Settings.getHeight() - InventoryBox.bg.getHeight() - 10);
}
inventoryBoxes[0].setSelected(true);
}
public void update(OrthoCamera gameCamera) {
camera.update();
stage.act(Gdx.graphics.getDeltaTime());
if (world.getPlayer().getInventory().wasChanged()) {
updateInventoryBoxes();
world.getPlayer().getInventory().resetChangedFlag();
}
if (moveControl.getTouchpad().isTouched()) {
if (moveControl.getTouchpad().getKnobPercentY() > .5f && world.getPlayer().canJump())
world.getPlayer().jump();
world.getPlayer().addVelocity(moveControl.getTouchpad().getKnobPercentX() * world.getPlayer().getSpeed(), 0);
} else if (actionControl.getTouchpad().isTouched()) {
ItemStack selectedItemStack = getSelectedItemStack();
if (selectedItemStack != null) {
if (selectedItemStack.getItem() instanceof ToolItem) {
if (selectedItemStack.getItem() instanceof CombatItem) {
LivingEntity entity = findLivingEntity((ToolItem) selectedItemStack.getItem()); //look for entities we can attack
if (entity != null) { //if we found an entity to attack, attack it
entity.damage(((CombatItem) selectedItemStack.getItem()).getDamage());
world.getPlayer().usedTool();
}
} else {
breakBlock((ToolItem) selectedItemStack.getItem());
}
} else if (selectedItemStack.getItem() instanceof BlockItem) {
placeBlock((BlockItem) selectedItemStack.getItem());
}
}
} else if (Gdx.input.isTouched(0)) {
float touchX = camera.unprojectXCoordinate(Gdx.input.getX(), Gdx.input.getY());
float touchY = camera.unprojectYCoordinate(Gdx.input.getX(), Gdx.input.getY());
for (InventoryBox box : inventoryBoxes) {
if (box.isPressed(touchX, touchY)) {
if (!box.isSelected()) {
unsetSelectedInventoryBox();
box.setSelected(true);
}
}
}
if (inventoryBtn.isPressed(touchX, touchY)) {
ScreenManager.setScreen(new InventoryScreen(gameScreen, world, world.getPlayer().getInventory()));
}
touchX = gameCamera.unprojectXCoordinate(Gdx.input.getX(), Gdx.input.getY());
touchY = gameCamera.unprojectYCoordinate(Gdx.input.getX(), Gdx.input.getY());
ItemStack selectedItemStack = getSelectedItemStack();
Vector2 origin = Vector2Factory.instance.getVector2(world.getPlayer().getX(), world.getPlayer().getY());
Vector2 position = Vector2Factory.instance.getVector2(touchX, touchY);
if (selectedItemStack != null) {
if(selectedItemStack.getItem() instanceof UsableItem){
UsableItem item = ((UsableItem) selectedItemStack.getItem());
if(new Vector2(touchX, touchY).dst(world.getPlayer().getX(), world.getPlayer().getY()) <= item.getReach()){
if(item.onUse(world, touchX, touchY)) {
highlightedBlockPosition.set(((int) touchX / ChunkManager.TILE_SIZE) * ChunkManager.TILE_SIZE, ((int) touchY / ChunkManager.TILE_SIZE) * ChunkManager.TILE_SIZE);
}
}
}
if (selectedItemStack.getItem() instanceof BlockItem) {
if (position.dst(origin) <= 100) {
BlockType type = world.getChunkManager().getBlockFromPos(touchX, touchY);
if (type == BlockType.AIR) {
if(world.getChunkManager().getChunkFromPos(touchX, touchY).findLivingEntitiesInRange(touchX, touchY, ChunkManager.TILE_SIZE).size == 0) {
highlightedBlockPosition.set(((int) touchX / ChunkManager.TILE_SIZE) * ChunkManager.TILE_SIZE, ((int) touchY / ChunkManager.TILE_SIZE) * ChunkManager.TILE_SIZE);
if (Timer.getGameTimeElapsed() - lastBlockPlace > .75f) {
if (world.getChunkManager().getBlockFromPos(touchX, touchY) == BlockType.AIR) {
collisionTestRect.set(highlightedBlockPosition.x, highlightedBlockPosition.y, ChunkManager.TILE_SIZE, ChunkManager.TILE_SIZE);
if (!world.getPlayer().getBounds().overlaps(collisionTestRect) || !BlockManager.getBlock(((BlockItem) selectedItemStack.getItem()).getBlockType()).collides()) {
world.getChunkManager().setBlock(((BlockItem) selectedItemStack.getItem()).getBlockType(), touchX, touchY, true);
world.getPlayer().getInventory().removeItemStack(selectedItemStack.getItem(), 1);
}
}
}
}
}
}
}
}
Vector2Factory.instance.destroy(origin);
Vector2Factory.instance.destroy(position);
} else {
highlightedBlockPosition.set(-100, -100);
}
}
public void render(OrthoCamera gameCamera) {
if (highlightedBlockPosition.x != -100 && highlightedBlockPosition.y != -100) { //means we are highlighting a block and trying to break it
sb.setProjectionMatrix(gameCamera.combined);
sb.begin();
blankTile.render(sb, highlightedBlockPosition.x, highlightedBlockPosition.y);
sb.end();
if(Gdx.input.isTouched()){
for(InventoryBox inventoryBox : inventoryBoxes){
if(inventoryBox.isSelected() && !(inventoryBox.getItemStack() == null)) {
Vector2 touchPosition = gameCamera.unprojectCoordinates(Gdx.input.getX(), Gdx.input.getY());
Drawable icon = inventoryBox.getItemStack().getItem().getIcon();
sb.begin();
icon.render(sb, touchPosition.x + icon.getWidth() * 1.5f, touchPosition.y); //drawn slightly to the side to avoid your finger overlapping the icon
sb.end();
}
}
}
}
sb.setProjectionMatrix(camera.combined);
sb.begin();
ResourceManager.getInstance().getFont("font").draw(sb, "FPS: " + Gdx.graphics.getFramesPerSecond(), Settings.getWidth() - 150, Settings.getHeight() - 60);
Chunk chunk = world.getChunkManager().getLoadedChunks()[1][1];
if (chunk != null) {
ResourceManager.getInstance().getFont("font").draw(sb, "Chunk: " + chunk.getStartX() + ", " + chunk.getStartY(), Settings.getWidth() - 150, Settings.getHeight() - 80);
}
int hearts = (int) world.getPlayer().getHealth() / 20;
for (int i = 0; i < hearts; i++) {
sb.draw(heartTexture, Settings.getWidth() - 75 - (i * (heartTexture.getWidth() + 5)), Settings.getHeight() - heartTexture.getHeight() - 15);
}
for (InventoryBox box : inventoryBoxes)
box.render(sb);
inventoryBtn.render(sb);
sb.end();
stage.draw();
}
public void renderBackground() {
sb.setProjectionMatrix(camera.combined);
sb.begin();
float value = DayManager.getInstance().getWorldLightValue();
sb.setColor(value, value, value, 1);
sb.draw(bg, 0, 0);
sb.setColor(Color.WHITE);
sb.end();
}
private LivingEntity findLivingEntity(ToolItem item) {
if (world.getPlayer().canUseItem(item)) {
Vector2 direction = Vector2Factory.instance.getVector2(actionControl.getTouchpad().getKnobPercentX(), actionControl.getTouchpad().getKnobPercentY()).nor(); //Get vector direction of the know
Chunk chunk = world.getChunkManager().getChunkFromPos(world.getPlayer().getX(), world.getPlayer().getY());
//The entities found array is sorted by distance to player from least to greatest
for (LivingEntity entity : chunk.findLivingEntitiesInRange(world.getPlayer().getX(), world.getPlayer().getY(), item.getReach())) {
if (direction.x < 0) {
if (entity.getX() < world.getPlayer().getX()) {
return entity;
}
} else if (direction.x >= 0) {
if (entity.getX() >= world.getPlayer().getX()) {
return entity;
}
}
}
}
return null;
}
private void breakBlock(ToolItem tool) {
Vector2 direction = Vector2Factory.instance.getVector2(actionControl.getTouchpad().getKnobPercentX(), actionControl.getTouchpad().getKnobPercentY()).nor(); //Get vector direction of the know
Vector2 foundBlockPos = world.getChunkManager().findBlock(tool, world.getPlayer().getX() + ChunkManager.TILE_SIZE / 2, world.getPlayer().getY() + ChunkManager.TILE_SIZE / 2, direction, tool.getReach()); //Find a block
if (direction.x != 0 && direction.y != 0) {
if (foundBlockPos != null) {
float px = ChunkManager.tileToPixelPosition((int) foundBlockPos.x);
float py = ChunkManager.tileToPixelPosition((int) foundBlockPos.y);
highlightedBlockPosition.set(px, py);
}
if (world.getPlayer().canUseItem(tool)) {
if (foundBlockPos != null) { //if block found within reach
if (world.getChunkManager().damageBlock((int) foundBlockPos.x, (int) foundBlockPos.y, tool.getPower())) { //Damage the block
world.getPlayer().usedTool();
}
}
}
}
Vector2Factory.instance.destroy(foundBlockPos);
Vector2Factory.instance.destroy(direction);
}
private void placeBlock(BlockItem block) {
Vector2 direction = Vector2Factory.instance.getVector2(actionControl.getTouchpad().getKnobPercentX(), actionControl.getTouchpad().getKnobPercentY()).nor(); //Get vector direction of the know
Vector2 foundBlockPos = world.getChunkManager().findFarthestAirBlock(world.getPlayer().getX() + ChunkManager.TILE_SIZE / 2, world.getPlayer().getY() + ChunkManager.TILE_SIZE / 2, direction, 100); //Find an air block
if (direction.x != 0 && direction.y != 0) {
if (foundBlockPos != null) { //if we found an air block
float px = ChunkManager.tileToPixelPosition((int) foundBlockPos.x);
float py = ChunkManager.tileToPixelPosition((int) foundBlockPos.y);
highlightedBlockPosition.set(px, py);
}
if (foundBlockPos != null) { //if block found within reach
if (Timer.getGameTimeElapsed() - lastBlockPlace > .75f) {
collisionTestRect.set(highlightedBlockPosition.x, highlightedBlockPosition.y, ChunkManager.TILE_SIZE, ChunkManager.TILE_SIZE);
if (!world.getPlayer().getBounds().overlaps(collisionTestRect)) {
world.getChunkManager().setBlock(block.getBlockType(), (int) foundBlockPos.x, (int) foundBlockPos.y, true);
world.getPlayer().getInventory().removeItemStack(block, 1);
lastBlockPlace = Timer.getGameTimeElapsed();
}
}
}
}
Vector2Factory.instance.destroy(foundBlockPos);
Vector2Factory.instance.destroy(direction);
}
public void updateInventoryBoxes() {
for (int i = 0; i < inventoryBoxes.length; i++) {
inventoryBoxes[i].setItemStack(world.getPlayer().getInventory().getItemStack(i, 0));
}
}
private void unsetSelectedInventoryBox() {
for (InventoryBox b : inventoryBoxes) {
if (b.isSelected()) {
b.setSelected(false);
break;
}
}
}
public ItemStack getSelectedItemStack() {
for (InventoryBox box : inventoryBoxes) {
if (box.isSelected()) {
return box.getItemStack();
}
}
return null;
}
public void resume() {
InputController.getInstance().addInputProcessor(stage);
}
public void dispose() {
InputController.getInstance().removeInputProcessor(stage);
}
public void resize(int width, int height) {
camera.resize();
}
}