package ee.futur.easygiantsfoundry; import ee.futur.easygiantsfoundry.enums.MetalBarSource; import ee.futur.easygiantsfoundry.enums.MetalBarType; import lombok.Getter; import lombok.Value; import net.runelite.api.Item; import net.runelite.api.ItemContainer; import net.runelite.api.gameval.InventoryID; import net.runelite.api.gameval.ItemID; import javax.inject.Inject; import javax.inject.Singleton; import java.util.HashMap; import java.util.Map; @Singleton public class MetalBarCounter { private final Map> index = new HashMap<>(); // container id -> bar counts @Inject private EasyGiantsFoundryConfig config; @Getter private boolean seenBank = false; public int get(MetalBarType type) { int count = 0; for (Map counts : index.values()) { count += counts.get(type).sum(config); } return count; } public void clear() { index.clear(); seenBank = false; } public void put(ItemContainer container) { int tinOre = 0; int copperOre = 0; int ironOre = 0; if (container.getId() == InventoryID.BANK) { seenBank = true; } Map counts = newCounts(); for (Item item : container.getItems()) { MetalBarValues.Record record = MetalBarValues.get(item.getId()); if (record == null) { continue; } // ore special cases: // * add bronze bars equal to min(tin, copper) // * there is an edge case here where it won't sum quite right multiple item containers but I don't really // care to code for that right now // * iron ore counts for both iron and steel switch (item.getId()) { case ItemID.TIN_ORE: case ItemID.Cert.TIN_ORE: tinOre += item.getQuantity(); break; case ItemID.COPPER_ORE: case ItemID.Cert.COPPER_ORE: copperOre += item.getQuantity(); break; case ItemID.IRON_ORE: case ItemID.Cert.IRON_ORE: ironOre += item.getQuantity(); break; default: counts.compute(record.getType(), (k, v) -> v.add(record.getSource(), record.getValue() * item.getQuantity())); } } int finalTinOre = tinOre; int finalCopperOre = copperOre; int finalIronOre = ironOre; counts.compute(MetalBarType.BRONZE, (k, v) -> v.add(MetalBarSource.ORE, Math.min(finalTinOre, finalCopperOre))); counts.compute(MetalBarType.IRON, (k, v) -> v.add(MetalBarSource.ORE, finalIronOre)); counts.compute(MetalBarType.STEEL, (k, v) -> v.add(MetalBarSource.ORE, finalIronOre)); index.put(container.getId(), counts); } private static Map newCounts() { Map counts = new HashMap<>(); counts.put(MetalBarType.BRONZE, CountsBySource.empty()); counts.put(MetalBarType.IRON, CountsBySource.empty()); counts.put(MetalBarType.STEEL, CountsBySource.empty()); counts.put(MetalBarType.MITHRIL, CountsBySource.empty()); counts.put(MetalBarType.ADAMANT, CountsBySource.empty()); counts.put(MetalBarType.RUNITE, CountsBySource.empty()); return counts; } @Value private static class CountsBySource { int ores, bars, equipment; public static CountsBySource empty() { return new CountsBySource(0, 0, 0); } public CountsBySource add(MetalBarSource source, int count) { switch (source) { case ORE: return new CountsBySource(ores + count, bars, equipment); case BAR: return new CountsBySource(ores, bars + count, equipment); case EQUIPMENT: return new CountsBySource(ores, bars, equipment + count); default: return this; } } public int sum(EasyGiantsFoundryConfig config) { int sum = config.countOre() ? ores : 0; sum += config.countBars() ? bars : 0; sum += config.countEquipment() ? equipment : 0; return sum; } } }