public static ManuQuote calculateQuote( Blueprint b, int runs, ManuQuote oldQuote, PriceDB pdb, BlueprintDB bdb, Preferences prefs, MatAcquirePriority mPrio) { // ---Skills and modifiers--- // Apply skills, implant and slotModifier. double time = b.getManuTime() * (1 - (0.04 * SKILL_LEVEL_VALUE[prefs.getSkillLvlIndex(Skill.INDUSTRY)])) * MOD_IMPLANT_VALUE[prefs.getImplantModIndex(ImplantMod.MOD_PE)] * MOD_SLOT_VALUE[prefs.getInstallationModIndex(InstallationMod.SLOT_MOD_PE)]; // Finalize time calculation. if ((b.getProductivityMod() / ((double) b.getManuTime())) <= 1) { if (b.getPe() >= 0) { time *= (1 - ((b.getProductivityMod() / ((double) b.getManuTime())) * (b.getPe() / ((double) (1 + b.getPe()))))); } else { time *= (1 - ((b.getProductivityMod() / ((double) b.getManuTime())) * (b.getPe() - 1))); } } double cost = 0, income = 0; // Base material list. ArrayList<Material> bML = new ArrayList<>(); // Extra material list. ArrayList<Material> eML = new ArrayList<>(); // Extra material recycle list. ArrayList<Material> eMRL = new ArrayList<>(); double amount; double afterRecycleAmount; // Divide the extra materials. for (Material m : b.getExtraMaterials()) { // Check if base materials already has a entry for the material. if (m.isRecycled()) { // Add to subtraction-list if item is recycled. for (Material m1 : m.getItem().getBaseMaterials()) { eMRL.add(new Material(m1.getItem(), m1.getAmount())); } } // Add skill waste. eML.add( new Material( m.getItem(), (m.getAmount() + (int) ((((25 - (5 * SKILL_LEVEL_VALUE[ prefs.getSkillLvlIndex(Skill.PRODUCTION_EFFICIENCY)])) * m.getAmount()) / 100) + 0.5)))); } // Calculate the correct amount of base materials including, skill and Me-based waste. for (Material m : b.getProduct().getBaseMaterials()) { afterRecycleAmount = m.getAmount(); // Remove recycled amount. if (eMRL.contains(m)) { afterRecycleAmount -= eMRL.get(eMRL.indexOf(m)).getAmount(); // Material amount can't be lower than 0. if (afterRecycleAmount < 0) { // Don't add the material, recycle has covered the amount. continue; } } // Set base. amount = afterRecycleAmount; // Add skill waste. amount += (int) ((((25 - (5 * SKILL_LEVEL_VALUE[prefs.getSkillLvlIndex(Skill.PRODUCTION_EFFICIENCY)])) * afterRecycleAmount) / 100) + 0.5); // Add ME waste. if (b.getMe() >= 0) { amount += (int) ((afterRecycleAmount * ((b.getWasteFactor()) / 100.0) * (1 / (double) (b.getMe() + 1))) + 0.5); } else { amount += (int) ((afterRecycleAmount * ((b.getWasteFactor()) / 100.0) * (1 - b.getMe())) + 0.5); } // Apply slot modifier. amount *= MOD_SLOT_VALUE[prefs.getInstallationModIndex(InstallationMod.SLOT_MOD_ME)]; bML.add(new Material(m.getItem(), (amount * runs))); } // Add extra materials to base-list. for (Material m : eML) { if (bML.contains(m)) { bML.get(bML.indexOf(m)) .setAmount(bML.get(bML.indexOf(m)).getAmount() + (m.getAmount() * runs)); } else { bML.add(new Material(m.getItem(), m.getAmount() * runs)); } } // ---PriceChecks--- // Calculate the cost for the Materials. for (Material m : bML) { m.setPrice(MarketCalculator.calculatePrice(Action.BUY, m.getItem().getTypeId(), pdb, prefs)); } // Do pre calculations of cost to decide how to acquire materials. for (Material m : bML) { cost += m.getPrice() * m.getAmount(); } // Installation cost. cost += prefs.getManufacturingCost(ManufacturingCost.INSTALLATION_COST) + time * prefs.getManufacturingCost(ManufacturingCost.INSTALLATION_COST_H) / 3600; // Income. income = b.getItemsPerRun() * runs * MarketCalculator.calculatePrice(Action.SELL, b.getProduct().getTypeId(), pdb, prefs); Blueprint tempB; // Add special manufacturing prices. for (Material m : bML) { // Add price to manufacture if applicable, otherwise add null. tempB = bdb.getByProductId(m.getItem().getTypeId()); if (tempB != null) { // Set default me/pe levels. tempB.setMe(prefs.getBlueprintStat(BlueprintStat.MOD_ME)); tempB.setPe(prefs.getBlueprintStat(BlueprintStat.MOD_PE)); m.setManufactureQuote(calculateQuote(tempB, 1, null, pdb, bdb, prefs, mPrio)); m.setCanBeManufactured(true); } else { m.setCanBeManufactured(false); m.setProduced(false); // Leave ManufactureQuote to null. } } // Set which prices to use, checks the values from the "oldQuote". if (oldQuote != null) { for (Material m1 : bML) { for (Material m : oldQuote.getMatList()) { if (m1.getItem().equals(m.getItem())) { m1.setProduced(m.isProduced()); break; } } } } // Set the values that were not set. for (Material m : bML) { if (m.isProduced() == null) { // Overrides priorities, if material can't be bought (price = 0), always produce. if (m.getPrice() == 0) { m.setProduced(true); } else if (mPrio == MatAcquirePriority.PROFIT_MARGIN && m.getManufactureQuote().getManuCost() < m.getPrice()) { // Set to true if the profit increases by manufacturing the material. m.setProduced(true); } else if (mPrio == MatAcquirePriority.PROFIT_PER_H_CHAIN && ((income - cost) * 3600) / (time * runs) < ((m.getPrice() - m.getManufactureQuote().getManuCost()) / m.getManufactureQuote().getManuTime().toHours())) { // Set to true if the profit/h increases by manufacturing the material in regard to the // time it takes. m.setProduced(true); } else { m.setProduced(false); } } } // Reset and re-do calculations. cost = 0; for (Material m : bML) { if (m.isProduced()) { cost += m.getManufactureQuote().getManuCost() * m.getAmount(); } else { cost += m.getPrice() * m.getAmount(); } } // Installation cost. cost += prefs.getManufacturingCost(ManufacturingCost.INSTALLATION_COST) + time * prefs.getManufacturingCost(ManufacturingCost.INSTALLATION_COST_H) / 3600; // Set the T1 BPO market availability. boolean seededOnMarket = b.getBlueprintItem().isOnMarket(); // Create quote. ManuQuote ans = new ManuQuote( b, new Time((int) (time + 0.5)), cost, income, income - cost, ((income - cost) * 3600) / (time * runs), calculateSalesVolumeRatio(b, pdb, time), runs, bML, mPrio, MarketCalculator.calculateMarketTrend(Action.SELL, b.getProduct(), pdb, prefs), seededOnMarket); // Set sustainableProfitValue. ans.setSustainableProfitValue(calculateSustainableProfitValue(ans)); return ans; }
public static ManuQuote calculateInventionQuote( Blueprint t2Bpo, int runs, ManuQuote oldQuote, PriceDB pdb, TechDB tdb, BlueprintDB bdb, Preferences prefs, InvPriority iPrio, MatAcquirePriority mPrio) { // Corresponding T1 blueprint. Blueprint t1Bpo = bdb.getByProductId(tdb.getParentId(t2Bpo.getProduct())); Blueprint cleanT2Bpo = bdb.getByBlueprintId(t2Bpo.getBlueprintItem().getTypeId()); // Variations. ArrayList<Decryptor> dL = t1Bpo.getInvDecryptors(); dL.add(null); // No decryptor. ArrayList<Item> iL = tdb.getT1Items(t1Bpo.getProduct().getTypeId()); iL.add(null); // No item. int[] rL = {1, t1Bpo.getMaxRuns()}; // Combination list. ArrayList<ManuQuote> qL = new ArrayList<>(); ManuQuote tmp = null; for (int t1BpcRuns : rL) { for (Item metaItem : iL) { for (Decryptor dec : dL) { // Only add quote if decryptor is available. if (dec == null || MarketCalculator.isItemAvailable(dec.getDecryptor(), pdb, prefs)) { // Get quote. tmp = calculateQuote( calculateInventionBPC(t1Bpo, cleanT2Bpo, metaItem, t1BpcRuns, dec, prefs), runs, oldQuote, pdb, bdb, prefs, mPrio); tmp.setInv( new Invention( calculateInventionChance(t1Bpo, metaItem, dec, prefs), dec, metaItem, t1BpcRuns, new Time( (int) (((t1Bpo.getCopyTime() * t1BpcRuns / (double) t1Bpo.getMaxRuns()) + 0.5) * MOD_COPY_VALUE[ prefs.getInstallationModIndex( InstallationMod .SLOT_MOD_COPY)])), // Divide copyTime with number of // max-runs. calculateInventionBPCRuns(t1Bpo, cleanT2Bpo, t1BpcRuns, dec), new Time(0, 0, 0, calculateInventionTime(t1Bpo, prefs)), iPrio)); qL.add(tmp); } } } } // Pick the best Quote according to priority. for (ManuQuote q : qL) { if (iPrio == InvPriority.PROFIT_MARGIN && q.getProfit() > tmp.getProfit()) { tmp = q; } else if (iPrio == InvPriority.PROFIT_PER_H && q.getProfitPerHour() > tmp.getProfitPerHour()) { tmp = q; } else if (iPrio == InvPriority.PROFIT_PER_COPY_H && q.getProfit() / (q.getInv().getCopyTime().toHours() * q.getInv().getT2BpcRuns() * q.getInv().getSuccessRate()) > tmp.getProfit() / (tmp.getInv().getCopyTime().toHours() * tmp.getInv().getT2BpcRuns() * tmp.getInv().getSuccessRate())) { tmp = q; } else if (iPrio == InvPriority.PROFIT_SUSTAINED && q.getSustainableProfitValue() > tmp.getSustainableProfitValue()) { tmp = q; } } // Set the T1 BPO market availability. tmp.setBaseBPOSeededOnMarket( MarketCalculator.isItemAvailable(t1Bpo.getBlueprintItem(), pdb, prefs)); return tmp; }