diff --git a/src/lib/turtle/InvManager.hx b/src/lib/turtle/InvManager.hx index 8d19f14..d9ec387 100644 --- a/src/lib/turtle/InvManager.hx +++ b/src/lib/turtle/InvManager.hx @@ -120,4 +120,117 @@ class InvManager { return Failure(failure); } } + + /** + Check what items in the inventory can be used as fuel. + **/ + public static function getCombustableItems():Array { + var invState = new InvState(); + var rtn = new Map(); + + for (slot => v in invState) { + if (rtn.exists(v.name)) { + continue; + } + + Turtle.selectSlot(slot); + var result = Turtle.canRefultWithSlot(); + + if (result) { + rtn.set(v.name, true); // How do i set a Noise type??? + } + } + + return [for (k => _ in rtn) k]; + } + + /** + Refule to a specific value. + Use array items first (in order). + Set `useAll` to false to don't use items not listes in priority. + **/ + public static function refuel(to:Int, priority:Array, useAll:Bool = true) { + var invState = new InvState(); + var fuelTo = MathI.min(to, Turtle.getFuelLimit()); + + if (Turtle.getFuelLevel() >= fuelTo) { + return; + } + + var items = invState.getSlotsForItems(); + + for (item in priority) { + if (!items.exists(item)) { + continue; + } + + var allSlotsWithItemOrderd = items.get(item); + allSlotsWithItemOrderd.sort((a, b) -> { + return invState.get(a).count - invState.get(b).count; + }); + + var fuelPerItem = 0; + + for (slot in allSlotsWithItemOrderd) { + var slotInfo = invState.get(slot); + Turtle.selectSlot(slot); + + if (fuelPerItem == 0) { + fuelPerItem = refuelFromSelectedSlot(slotInfo.count, fuelTo); + if (fuelPerItem == 0) { + Log.warn('Item ${slotInfo.name} is not combustable'); + continue; + } + } else { + var itemsToUse = MathI.min(Math.ceil((fuelTo - (Turtle.getFuelLevel())) / fuelPerItem), slotInfo.count); + Turtle.refuel(itemsToUse); + } + + if (Turtle.getFuelLevel() >= fuelTo) { + return; + } + } + } + + // If not reached our goal yet, check all other items to use as fuel. + if (!useAll) { + return; + } + + for (slot => slotInfo in invState) { + // Skip items that we already checked + // Also the invstate might be invalid for these slots + if (priority.contains(slotInfo.name)) { + continue; + } + + Turtle.selectSlot(slot); + refuelFromSelectedSlot(slotInfo.count, fuelTo); + + if (Turtle.getFuelLevel() >= fuelTo) { + return; + } + } + } + + /** + Refuel from selected slot. The ammount of items in the slot must be given. + The `to` arg should be the desired fuel level. + Returns the ammount of fuel on item of this kind refuels. + Returns 0 of item is not combustable. + **/ + private static function refuelFromSelectedSlot(count:Int, to:Int):Int { + var fuelLevel = Turtle.getFuelLevel(); + + if (!Turtle.refuel(1).isSuccess()) { + return 0; + } + + var fuelPerItem = Turtle.getFuelLevel() - fuelLevel; + var itemsToUse = MathI.min(Math.ceil((to - (fuelLevel + fuelPerItem)) / fuelPerItem), count - 1); + + Turtle.refuel(itemsToUse); + + return fuelPerItem; + } }