package de.phbouillon.android.games.alite.screens.canvas; /* Alite - Discover the Universe on your Favorite Android Device * Copyright (C) 2015 Philipp Bouillon * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful and * fun, 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 General Public License * along with this program. If not, see * http://http://www.gnu.org/licenses/gpl-3.0.txt. */ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Locale; import de.phbouillon.android.framework.Game; import de.phbouillon.android.framework.Graphics; import de.phbouillon.android.framework.Pixmap; import de.phbouillon.android.games.alite.Alite; import de.phbouillon.android.games.alite.AliteLog; import de.phbouillon.android.games.alite.Assets; import de.phbouillon.android.games.alite.Button; import de.phbouillon.android.games.alite.ScreenCodes; import de.phbouillon.android.games.alite.Settings; import de.phbouillon.android.games.alite.SoundManager; import de.phbouillon.android.games.alite.colors.AliteColors; import de.phbouillon.android.games.alite.model.EquipmentStore; import de.phbouillon.android.games.alite.model.InventoryItem; import de.phbouillon.android.games.alite.model.Player; import de.phbouillon.android.games.alite.model.PlayerCobra; import de.phbouillon.android.games.alite.model.Weight; import de.phbouillon.android.games.alite.model.missions.Mission; import de.phbouillon.android.games.alite.model.trading.Market; import de.phbouillon.android.games.alite.model.trading.TradeGood; import de.phbouillon.android.games.alite.model.trading.TradeGoodStore; import de.phbouillon.android.games.alite.model.trading.Unit; import de.phbouillon.android.games.alite.screens.opengl.ingame.FlightScreen; import de.phbouillon.android.games.alite.screens.opengl.ingame.InGameManager; //This screen never needs to be serialized, as it is not part of the InGame state. @SuppressWarnings("serial") public class InventoryScreen extends TradeScreen { static class InventoryPair { TradeGood good; InventoryItem item; InventoryPair(TradeGood good, InventoryItem item) { this.good = good; this.item = item; } } private static final String INVENTORY_HINT = "(Tap again to sell)"; private static final String EJECT_HINT = "(Tap again to eject)"; private final ArrayList<InventoryPair> inventoryList = new ArrayList<InventoryPair>(); private Pixmap [] tradegoods; private Pixmap [] beam; private Pixmap thargoidDocuments; private Pixmap unhappyRefugees; private String pendingSelection = null; public InventoryScreen(Game game) { super(game, 0); X_OFFSET = 50; GAP_X = 270; GAP_Y = 290; COLUMNS = 6; } @Override public void activate() { createButtons(); if (pendingSelection != null) { for (Button [] bs: tradeButton) { if (bs == null) { continue; } for (Button b: bs) { if (b == null || b.getName() == null) { continue; } if (pendingSelection.equals(b.getName())) { selection = b; b.setSelected(true); } } } pendingSelection = null; } } public static boolean initialize(Alite alite, final DataInputStream dis) { InventoryScreen is = new InventoryScreen(alite); try { byte selectionLength = dis.readByte(); if (selectionLength > 0) { is.pendingSelection = ""; while (selectionLength > 0) { is.pendingSelection += dis.readChar(); selectionLength--; } } } catch (Exception e) { AliteLog.e("Inventory Screen Initialize", "Error in initializer.", e); return false; } alite.setScreen(is); return true; } @Override public void saveScreenState(DataOutputStream dos) throws IOException { dos.writeByte(selection == null ? 0 : selection.getName().length()); if (selection != null) { dos.writeChars(selection.getName()); } } @Override protected void createButtons() { PlayerCobra cobra = ((Alite) game).getPlayer().getCobra(); InventoryItem [] inventory = cobra.getInventory(); inventoryList.clear(); int counter = 0; for (InventoryItem item: inventory) { if (item.getWeight().getWeightInGrams() != 0) { inventoryList.add(new InventoryPair(TradeGoodStore.get().goods()[counter], item)); } counter++; } tradeButton = new Button[COLUMNS][ROWS]; for (int x = 0; x < COLUMNS; x++) { for (int y = 0; y < ROWS; y++) { tradeButton[x][y] = null; } } int y = 0; int x = 0; for (InventoryPair pair: inventoryList) { tradeButton[x][y] = new Button(x * GAP_X + X_OFFSET, y * GAP_Y + Y_OFFSET, SIZE, SIZE, tradegoods[TradeGoodStore.get().ordinal(pair.good)], beam); tradeButton[x][y].setName(pair.good.getName()); tradeButton[x][y].setUseBorder(false); x++; if (x == COLUMNS) { x = 0; y++; } } renderSpecialCargo(x, y); } private void renderSpecialCargo(int x, int y) { PlayerCobra cobra = ((Alite) game).getPlayer().getCobra(); Weight w = cobra.getSpecialCargo("Thargoid Documents"); if (w != null) { tradeButton[x][y] = new Button(x * GAP_X + X_OFFSET, y * GAP_Y + Y_OFFSET, SIZE, SIZE, thargoidDocuments, beam); tradeButton[x][y].setUseBorder(false); x++; if (x == COLUMNS) { x = 0; y++; } } w = cobra.getSpecialCargo("Unhappy Refugees"); if (w != null) { tradeButton[x][y] = new Button(x * GAP_X + X_OFFSET, y * GAP_Y + Y_OFFSET, SIZE, SIZE, unhappyRefugees, beam); tradeButton[x][y].setUseBorder(false); } } private long cap(long value) { String binary = Long.toBinaryString(value); if (binary.length() > 32) { binary = binary.substring(binary.length() - 32); return Long.parseLong(binary, 2); } return value; } private long computePrice(Market market, int factor, long weightInGrams, TradeGood good) { long tradeGoodPrice = (market.getPrice(good) * 19 * 4) / 20; long price = ((weightInGrams / factor) + (weightInGrams % factor != 0 ? 1 : 0)) * tradeGoodPrice; price = cap(price) / 4; return price; } private String computeCashString(InventoryPair pair) { Market market = ((Alite) game).getPlayer().getMarket(); int factor = pair.good.getUnit() == Unit.TON ? 1000000 : pair.good.getUnit() == Unit.KILOGRAM ? 1000 : 1; long price = computePrice(market, factor, pair.item.getWeight().getWeightInGrams(), pair.good); return String.format(Locale.getDefault(), "%d.%d Cr", price / 10, price % 10); } private String computeGainLossString(InventoryPair pair) { Market market = ((Alite) game).getPlayer().getMarket(); int factor = pair.good.getUnit() == Unit.TON ? 1000000 : pair.good.getUnit() == Unit.KILOGRAM ? 1000 : 1; long price = computePrice(market, factor, pair.item.getWeight().getWeightInGrams(), pair.good); long gain = price - pair.item.getPrice(); boolean loss = false; if (gain < 0) { loss = true; gain = -gain; } return (loss ? "Loss: -" : "Gain: ") + String.format(Locale.getDefault(), "%d.%d Cr", gain / 10, gain % 10); } @Override protected String getCost(int row, int column) { int index = row * COLUMNS + column; if (index >= inventoryList.size()) { return ""; } InventoryPair pair = inventoryList.get(index); return pair.item.getWeight().getFormattedString(); } @Override public void present(float deltaTime) { if (disposed) { return; } Graphics g = game.getGraphics(); g.clear(AliteColors.get().background()); displayTitle("Inventory"); if (inventoryList.isEmpty()) { if (!((Alite) game).getCobra().containsSpecialCargo()) { g.drawText("Cargo hold is empty.", 180, 200, AliteColors.get().warningMessage(), Assets.regularFont); } } presentTradeGoods(deltaTime); presentTradeStatus(); } @Override protected void presentSelection(int row, int column) { int index = row * COLUMNS + column; if (index >= inventoryList.size()) { try { if (tradeButton[column][row] != null && tradeButton[column][row].getPixmap() == thargoidDocuments) { game.getGraphics().drawText("Important Thargoid Documents", X_OFFSET, 1050, AliteColors.get().message(), Assets.regularFont); } else if (tradeButton[column][row] != null && tradeButton[column][row].getPixmap() == unhappyRefugees) { game.getGraphics().drawText("Unhappy Refugees", X_OFFSET, 1050, AliteColors.get().message(), Assets.regularFont); } } catch (IndexOutOfBoundsException e) { // Ignore. } return; } InventoryPair pair = inventoryList.get(index); TradeGood tradeGood = pair.good; String worthText = tradeGood.getName() + " - worth: " + computeCashString(pair) + ". "; int width = game.getGraphics().getTextWidth(worthText, Assets.regularFont); game.getGraphics().drawText(worthText, X_OFFSET, 1050, AliteColors.get().message(), Assets.regularFont); String gainText = computeGainLossString(pair) + ". "; int widthComplete = width + game.getGraphics().getTextWidth(gainText, Assets.regularFont); game.getGraphics().drawText(gainText, X_OFFSET + width, 1050, gainText.startsWith("Loss") ? AliteColors.get().conditionRed() : AliteColors.get().conditionGreen(), Assets.regularFont); Alite alite = (Alite) game; if (alite.getCurrentScreen() instanceof FlightScreen && alite.getCobra().isEquipmentInstalled(EquipmentStore.fuelScoop)) { game.getGraphics().drawText(EJECT_HINT, X_OFFSET + widthComplete, 1050, AliteColors.get().message(), Assets.regularFont); } else { game.getGraphics().drawText(INVENTORY_HINT, X_OFFSET + widthComplete, 1050, AliteColors.get().message(), Assets.regularFont); } } protected void performTradeWhileInFlight(int row, int column) { if (!((Alite) game).getCobra().isEquipmentInstalled(EquipmentStore.fuelScoop)) { super.performTradeWhileInFlight(row, column); return; } SoundManager.play(Assets.retroRocketsOrEscapeCapsuleFired); int index = row * COLUMNS + column; if (index >= inventoryList.size()) { return; } InventoryPair pair = inventoryList.get(index); TradeGood tradeGood = pair.good; Player player = ((Alite) game).getPlayer(); Weight ejectedWeight; long ejectedPrice = pair.item.getPrice(); if (pair.item.getWeight().compareTo(Weight.tonnes(4)) < 0) { ejectedWeight = pair.item.getWeight(); player.getCobra().removeTradeGood(tradeGood); } else { ejectedWeight = Weight.tonnes(4); player.getCobra().setTradeGood(tradeGood, pair.item.getWeight().sub(ejectedWeight), pair.item.getPrice()); player.getCobra().subUnpunishedTradeGood(tradeGood, ejectedWeight); } InGameManager manager = ((FlightScreen) ((Alite) game).getCurrentScreen()).getInGameManager(); manager.getLaserManager().ejectPlayerCargoCanister(manager.getShip(), tradeGood, ejectedWeight, ejectedPrice); createButtons(); } @Override public void performTrade(int row, int column) { int index = row * COLUMNS + column; if (index >= inventoryList.size()) { return; } InventoryPair pair = inventoryList.get(index); TradeGood tradeGood = pair.good; Player player = ((Alite) game).getPlayer(); for (Mission m: player.getActiveMissions()) { if (m.performTrade(this, tradeGood)) { return; } } Market market = player.getMarket(); int factor = pair.good.getUnit() == Unit.TON ? 1000000 : pair.good.getUnit() == Unit.KILOGRAM ? 1000 : 1; long price = computePrice(market, factor, pair.item.getWeight().getWeightInGrams(), pair.good); int chanceInPercent = ((Alite) game).getPlayer().getLegalProblemLikelihoodInPercent(); if (Math.random() * 100 < chanceInPercent) { ((Alite) game).getPlayer().setLegalValue( ((Alite) game).getPlayer().getLegalValue() + (int) (tradeGood.getLegalityType() * pair.item.getUnpunished().getQuantityInAppropriateUnit())); } player.getCobra().removeTradeGood(tradeGood); player.setCash(player.getCash() + price); cashLeft = String.format("Cash: %d.%d Cr", player.getCash() / 10, player.getCash() % 10); SoundManager.play(Assets.kaChing); createButtons(); try { ((Alite) game).getFileUtils().autoSave((Alite) game); } catch (IOException e) { AliteLog.e("Auto saving failed", e.getMessage(), e); } } public String getCashLeft() { return cashLeft; } private void readBeamAnimation(final Graphics g) { beam = new Pixmap[16]; beam[0] = g.newPixmap("trade_icons/beam.png", true); for (int i = 1; i < 16; i++) { beam[i] = g.newPixmap("trade_icons/beam/" + i + ".png", true); } } private void readTradegoods(final Graphics g) { tradegoods = new Pixmap[18]; tradegoods[ 0] = g.newPixmap("trade_icons/food.png", true); tradegoods[ 1] = g.newPixmap("trade_icons/textiles.png", true); tradegoods[ 2] = g.newPixmap("trade_icons/radioactives.png", true); tradegoods[ 3] = g.newPixmap("trade_icons/slaves.png", true); tradegoods[ 4] = g.newPixmap("trade_icons/liquor_wines.png", true); tradegoods[ 5] = g.newPixmap("trade_icons/luxuries.png", true); tradegoods[ 6] = g.newPixmap("trade_icons/narcotics.png", true); tradegoods[ 7] = g.newPixmap("trade_icons/computers.png", true); tradegoods[ 8] = g.newPixmap("trade_icons/machinery.png", true); tradegoods[ 9] = g.newPixmap("trade_icons/alloys.png", true); tradegoods[10] = g.newPixmap("trade_icons/firearms.png", true); tradegoods[11] = g.newPixmap("trade_icons/furs.png", true); tradegoods[12] = g.newPixmap("trade_icons/minerals.png", true); tradegoods[13] = g.newPixmap("trade_icons/gold.png", true); tradegoods[14] = g.newPixmap("trade_icons/platinum.png", true); tradegoods[15] = g.newPixmap("trade_icons/gem_stones.png", true); tradegoods[16] = g.newPixmap("trade_icons/alien_items.png", true); tradegoods[17] = g.newPixmap("trade_icons/medical_supplies.png", true); } @Override public void loadAssets() { Graphics g = game.getGraphics(); if (beam == null && Settings.animationsEnabled) { readBeamAnimation(g); } if (tradegoods == null) { readTradegoods(g); } if (thargoidDocuments == null) { thargoidDocuments = g.newPixmap("trade_icons/thargoid_documents.png", true); } if (unhappyRefugees == null) { unhappyRefugees = g.newPixmap("trade_icons/unhappy_refugees.png", true); } super.loadAssets(); } @Override public void dispose() { super.dispose(); if (beam != null) { for (Pixmap p: beam) { p.dispose(); } beam = null; } if (tradegoods != null) { for (Pixmap p: tradegoods) { p.dispose(); } tradegoods = null; } if (thargoidDocuments != null) { thargoidDocuments.dispose(); thargoidDocuments = null; } if (unhappyRefugees != null) { unhappyRefugees.dispose(); unhappyRefugees = null; } } @Override public void pause() { super.pause(); } @Override public void resume() { super.resume(); } @Override public int getScreenCode() { return ScreenCodes.INVENTORY_SCREEN; } }