package com.jmrapp.terralegion.game.views.screen; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.Group; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.ui.Cell; import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Array; 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.utils.Settings; import com.jmrapp.terralegion.engine.views.drawables.ResourceManager; import com.jmrapp.terralegion.engine.views.drawables.ui.Label; import com.jmrapp.terralegion.engine.views.drawables.ui.MultilineLabel; import com.jmrapp.terralegion.engine.views.drawables.ui.PictureButton; import com.jmrapp.terralegion.engine.views.screens.Screen; import com.jmrapp.terralegion.engine.views.screens.ScreenManager; import com.jmrapp.terralegion.game.item.ItemCategory; import com.jmrapp.terralegion.game.item.ItemStack; import com.jmrapp.terralegion.game.item.crafting.CraftingRecipe; import com.jmrapp.terralegion.game.item.crafting.CraftingRecipes; import com.jmrapp.terralegion.game.item.inventory.Inventory; import com.jmrapp.terralegion.game.views.ui.ItemBox; import com.jmrapp.terralegion.game.utils.CachePool; import com.jmrapp.terralegion.game.world.World; /** * Created by Jon on 10/8/15. */ public class CraftingScreen implements Screen { private static final int MAX_TABLE_WIDTH = 5; private static final Texture bg = ResourceManager.getInstance().getTexture("craftingBg"); private static final TextureRegionDrawable inventoryBoxDrawable = new TextureRegionDrawable(new TextureRegion(ResourceManager.getInstance().getTexture("inventoryBox"))); private static final TextureRegionDrawable inventorySelectedBoxDrawable = new TextureRegionDrawable(new TextureRegion(ResourceManager.getInstance().getTexture("selectedInventoryBox"))); private CategoryButton toolCategoryBtn = new CategoryButton(ItemCategory.TOOL, ResourceManager.getInstance().getTexture("unselectedToolCategoryBtn"), ResourceManager.getInstance().getTexture("selectedToolCategoryBtn"), 30, Settings.getHeight() - 120); private CategoryButton furnitureCategoryBtn = new CategoryButton(ItemCategory.FURNITURE, ResourceManager.getInstance().getTexture("unselectedToolCategoryBtn"), ResourceManager.getInstance().getTexture("selectedToolCategoryBtn"), 30, Settings.getHeight() - 170); private static final Array<Table> usedTablesCache = new Array<Table>(); private static final Array<Group> usedGroupsCache = new Array<Group>(); private static final Array<InventoryDragListener> dragListenersCache = new Array<InventoryDragListener>(InventoryDragListener.class); private static final Array<InventoryDragListener> usedDragListenersCache = new Array<InventoryDragListener>(); private Stage stage; private SpriteBatch stageSb; private OrthoCamera camera; private final World world; private final Inventory inventory; private final Screen gameScreen; private ItemBox selectedInventoryBox; private Label itemNameLabel; private MultilineLabel itemInfoLabel; private Table craftingTable; private ScrollPane pane; private ItemCategory currentCategory; private CraftingRecipe selectedRecipe; private PictureButton cancelBtn = new PictureButton(ResourceManager.getInstance().getDrawable("cancelBtn"), Settings.getWidth() - ResourceManager.getInstance().getDrawable("cancelBtn").getWidth() - 15, Settings.getHeight() - 61 + 10); private PictureButton craftingBtn = new PictureButton(ResourceManager.getInstance().getDrawable("selectedCraftingBtn"), 30, Settings.getHeight() - 61 + 10); private PictureButton invBtn = new PictureButton(ResourceManager.getInstance().getDrawable("unselectedInvBtn"), (Settings.getWidth() / 2) - 25, Settings.getHeight() - 61 + 10); private PictureButton craftBtn = new PictureButton(ResourceManager.getInstance().getDrawable("craftBtn"), Settings.getWidth() - 200, 25); public CraftingScreen(Screen gameScreen, World world, Inventory inventory) { this.gameScreen = gameScreen; this.world = world; this.inventory = inventory; } @Override public void create() { camera = new OrthoCamera(); camera.resize(); stageSb = new SpriteBatch(); stage = new Stage(new StretchViewport(Settings.getWidth(), Settings.getHeight()), stageSb); //CATEGORY BUTTONS stage.addActor(toolCategoryBtn.getImageButton()); stage.addActor(furnitureCategoryBtn.getImageButton()); ScrollPane.ScrollPaneStyle paneStyle = new ScrollPane.ScrollPaneStyle(); paneStyle.background = new TextureRegionDrawable(new TextureRegion(ResourceManager.getInstance().getTexture("invStageBg"))); //paneStyle.vScrollKnob = new TextureRegionDrawable(); //paneStyle.hScroll = paneStyle.hScrollKnob = paneStyle.vScroll = paneStyle.vScrollKnob; Table craftingContainer = CachePool.getTable(); usedTablesCache.add(craftingContainer); float startX = (Settings.getWidth() / 2) - 255; craftingContainer.setBounds(startX, 0, 370, Settings.getHeight() - 61); craftingTable = CachePool.getTable(); stage.addListener(new CraftingButtonClickListener(stage, craftingTable, craftingContainer.getX(), craftingContainer.getY())); usedTablesCache.add(craftingTable); pane = new ScrollPane(craftingTable, paneStyle); craftingContainer.add(pane).width(370).height(Settings.getHeight() - 61); craftingContainer.row(); stage.addActor(craftingContainer); itemNameLabel = new Label("", ResourceManager.getInstance().getFont("font"), startX + 370 + 10, Settings.getHeight() - 61 - 35, false); itemInfoLabel = new MultilineLabel("", ResourceManager.getInstance().getFont("font"), startX + 370 + 10, Settings.getHeight() - 61 - 85, false); populateCraftableItems(toolCategoryBtn.getCategory()); InputController.getInstance().addInputProcessor(stage); } @Override public void update() { camera.update(); stage.act(Gdx.graphics.getDeltaTime()); if (Gdx.input.justTouched()) { float touchX = camera.unprojectXCoordinate(Gdx.input.getX(), Gdx.input.getY()); float touchY = camera.unprojectYCoordinate(Gdx.input.getX(), Gdx.input.getY()); if (cancelBtn.isPressed(touchX, touchY)) { ScreenManager.setScreen(gameScreen); } else if (invBtn.isPressed(touchX, touchY)) { ScreenManager.setScreen(new InventoryScreen(gameScreen, world, inventory)); } else if (selectedRecipe != null && craftBtn.isPressed(touchX, touchY)) { // check if user can craft the selected item/block if(selectedRecipe.canCraft(inventory)) { // give the player the crafted item/block inventory.addItemStack(selectedRecipe.craft(inventory)); // also removes required items updateSelectedRecipeInfo(); } } } } @Override public void render(SpriteBatch sb) { sb.setProjectionMatrix(camera.combined); sb.begin(); sb.draw(bg, 0, 0); itemNameLabel.render(sb); itemInfoLabel.render(sb); cancelBtn.render(sb); craftingBtn.render(sb); invBtn.render(sb); if (selectedRecipe != null) craftBtn.render(sb); sb.end(); stage.draw(); } @Override public void dispose() { InputController.getInstance().removeInputProcessor(stage); stage.dispose(); for (int i = 0; i < usedTablesCache.size; i++) { //Manage the tables so we don't over use them each time we open the inventory screen CachePool.addTable(usedTablesCache.get(i)); } usedTablesCache.clear(); for (int i = 0; i < usedGroupsCache.size; i++) { CachePool.addGroup(usedGroupsCache.get(i)); } usedGroupsCache.clear(); for (int i = 0; i < usedDragListenersCache.size; i++) { dragListenersCache.add(usedDragListenersCache.get(i)); } dragListenersCache.clear(); } @Override public void resize(int width, int height) { camera.resize(); } @Override public void onBackPressed() { ScreenManager.goBack(); } @Override public void pause() { } @Override public void resume() { InputController.getInstance().addInputProcessor(stage); } private void populateCraftableItems(ItemCategory category) { craftingTable.clear(); currentCategory = category; itemNameLabel.setText(""); itemInfoLabel.setText(""); Array<CraftingRecipe> recipes = CraftingRecipes.getInstance().getCraftableItems(category); int y = 0; for (int i = 0; i < recipes.size; i++) { ItemStack stack = recipes.get(i).getCraftedItemStack(); ItemBox box = new ItemBox(stack, String.valueOf(i)); Cell<Table> cell = craftingTable.add((Table) box).width(60).height(60).padRight(10).padBottom(10); if (i % MAX_TABLE_WIDTH == 0) { cell.padLeft(10); } if (y == 0) { cell.padTop(10); } if ((i + 1) % MAX_TABLE_WIDTH == 0) { craftingTable.row(); y++; } } } private void updateSelectedRecipeInfo() { ItemStack itemStack = selectedRecipe.getCraftedItemStack(); if (itemStack != null) { itemNameLabel.setText(itemStack.getItem().getName()); String text = ""; for (ItemStack stack : selectedRecipe.getRequiredItems()) { text += stack.getItem().getName() + "(" + inventory.getTotalCount(stack.getItem()) + "/" + stack.getStack() + ")\n"; } itemInfoLabel.setText(text); } } private class CraftingButtonClickListener extends ClickListener { private Stage stage; private Table craftingHolder; private float tableOffsetX, tableOffsetY; public CraftingButtonClickListener(Stage stage, Table craftingHolder, float tableOffsetX, float tableOffsetY) { this.stage = stage; this.craftingHolder = craftingHolder; this.tableOffsetX = tableOffsetX; this.tableOffsetY = tableOffsetY; } @Override public void clicked(InputEvent event, float xClick, float yClick) { for (Actor actor : stage.getActors()) { if (actor instanceof ImageButton) { ImageButton btn = (ImageButton) actor; float boxX = btn.getX(); float boxY = btn.getY(); float boxWidth = btn.getWidth(); float boxHeight = btn.getHeight(); if (xClick >= boxX && xClick <= boxX + boxWidth && yClick >= boxY && yClick <= boxY + boxHeight) { //dropped on itembox String[] split = actor.getName().split(" "); if (split[0].equals("category")) { //It's a category button so switch categories if (btn == toolCategoryBtn.getImageButton()) { populateCraftableItems(toolCategoryBtn.getCategory()); } else if (btn == furnitureCategoryBtn.getImageButton()) { populateCraftableItems(furnitureCategoryBtn.getCategory()); } return; } } } } for (Actor actor : craftingHolder.getChildren()) { if (actor instanceof ItemBox) { ItemBox box = (ItemBox) actor; if (box != selectedInventoryBox) { float boxX = box.getX() + tableOffsetX; float boxY = box.getY() + tableOffsetY; float boxWidth = box.getWidth(); float boxHeight = box.getHeight(); if (xClick >= boxX && xClick <= boxX + boxWidth && yClick >= boxY && yClick <= boxY + boxHeight) { //dropped on itembox box.setSelected(true); if (selectedInventoryBox != null) { selectedInventoryBox.setSelected(false); } selectedInventoryBox = box; //selected a craftable item Array<CraftingRecipe> recipes = CraftingRecipes.getInstance().getCraftableItems(currentCategory); int index = Integer.parseInt(box.getExtra()); selectedRecipe = recipes.get(index); updateSelectedRecipeInfo(); break; } } } } } } private class CategoryButton { private ImageButton cachedButton; private ItemCategory category; private Texture upTexture, downTexture; private float x, y; public CategoryButton(ItemCategory category, Texture upTexture, Texture downTexture, float x, float y) { this.category = category; this.upTexture = upTexture; this.downTexture = downTexture; this.x = x; this.y = y; } public ItemCategory getCategory() { return category; } public ImageButton getImageButton() { if (cachedButton == null) { ImageButton.ImageButtonStyle style = new ImageButton.ImageButtonStyle(); style.up = new TextureRegionDrawable(new TextureRegion(upTexture)); style.down = new TextureRegionDrawable(new TextureRegion(downTexture)); cachedButton = new ImageButton(style); cachedButton.setBounds(x, y, upTexture.getWidth(), upTexture.getHeight()); cachedButton.setName("category "); return cachedButton; } return cachedButton; } } }