diff --git a/src/lib/turtle/InvManager.hx b/src/lib/turtle/InvManager.hx index f89bd88..8d19f14 100644 --- a/src/lib/turtle/InvManager.hx +++ b/src/lib/turtle/InvManager.hx @@ -9,123 +9,28 @@ import kernel.turtle.Turtle; using Lambda; using tink.CoreApi; -typedef InvState = Map; - /** A wrapper for the native turtle inventory functions. Adds usefullt helper functions. **/ class InvManager { - public function new() {} - - private static function getInvState() { - var invState:InvState = new Map(); - for (i in 0...Turtle.MAX_SLOTS) { - var detail = Turtle.getItemDetail(i); - var spaceLeft = Turtle.getItemSpace(i); - - switch detail { - case Some(v): - invState.set(i, { - count: v.count, - name: v.name, - max: spaceLeft + v.count - }); - case None: - invState.remove(i); - } - } - return invState; - } - - public static function getItemCountInfo():Map { - var invState = getInvState(); - var rtn:Map = new Map(); - - for (slot in invState) { - if (!rtn.exists(slot.name)) { - rtn.set(slot.name, slot.count); - continue; - } - - var count = rtn.get(slot.name); - rtn.set(slot.name, count + slot.count); - } - - return rtn; - } - - private static function getSlotWithMinCountForItem(item:Item, invState:InvState):Null { - var min:Int = 99; // TODO: is there something like MAX_INT ??? - var minSlot:TurtleSlot = -1; - - for (k => slot in invState) { - if (slot.name != item) { - continue; - } - - if (slot.count < min) { - min = slot.count; - minSlot = k; - } - }; - - return minSlot == -1 ? null : minSlot; - } - public static function place(item:Item, dir:InteractDirections):Outcome { - var invState = getInvState(); - var slot = getSlotWithMinCountForItem(item, invState); + var invState = new InvState(); + var slot = invState.getSlotWithMinCountForItem(item); if (slot == null) { return Failure("Item not in inventory"); } - return placeSlot(slot, dir); - } - - private static function placeSlot(slot:TurtleSlot, dir:InteractDirections):Outcome { - Turtle.selectSlot(slot); // TODO: handle error + Turtle.selectSlot(slot); return Turtle.place(dir); } - private static function getSlotsForItems(invState:InvState):Map> { - var rtn:Map> = new Map(); - - for (k => slot in invState) { - if (!rtn.exists(slot.name)) { - rtn.set(slot.name, [k]); - continue; - } - - var value = rtn.get(slot.name); - value.push(k); - rtn.set(slot.name, value); - } - - return rtn; - } - - /** - Returns the first slot that contains this item. - **/ - public static function findItemSlot(item:Item):Null { - var invState = getInvState(); - - for (k => slot in invState) { - if (slot.name == item) { - return k; - } - } - - return null; - } - /** Cleans up turtle inventory. Moves items together. This should be run in a turtle thread. **/ public static function defrag() { - var invState = getInvState(); - var items = getSlotsForItems(invState); + var invState = new InvState(); + var items = invState.getSlotsForItems(); for (item in items) { defragItem(invState, item); @@ -198,7 +103,8 @@ class InvManager { } public static function equipTool(item:Item, side:ToolSide):Outcome { - var toolSlot = findItemSlot(item); + var invState = new InvState(); + var toolSlot = invState.findItemSlot(item); if (toolSlot == null) { return Failure("Item not found"); diff --git a/src/lib/turtle/InvState.hx b/src/lib/turtle/InvState.hx new file mode 100644 index 0000000..8beb6a1 --- /dev/null +++ b/src/lib/turtle/InvState.hx @@ -0,0 +1,99 @@ +package lib.turtle; + +import kernel.turtle.Turtle; +import kernel.turtle.TurtleSlot; + +@:forward(get, set, iterator, keyValueIterator) +abstract InvState(Map) { + public function new() { + this = new Map(); + for (i in 0...Turtle.MAX_SLOTS) { + var detail = Turtle.getItemDetail(i); + var spaceLeft = Turtle.getItemSpace(i); + + switch detail { + case Some(v): + this.set(i, { + count: v.count, + name: v.name, + max: spaceLeft + v.count + }); + case None: + this.remove(i); + } + } + } + + /** + Count items. + **/ + public function getItemCountInfo():Map { + var rtn:Map = new Map(); + + for (slot in this) { + if (!rtn.exists(slot.name)) { + rtn.set(slot.name, slot.count); + continue; + } + + var count = rtn.get(slot.name); + rtn.set(slot.name, count + slot.count); + } + + return rtn; + } + + /** + Return the slot with with the minimal count for an item. + **/ + public function getSlotWithMinCountForItem(item:Item):Null { + var min:Int = 99; // TODO: is there something like MAX_INT ??? + var minSlot:TurtleSlot = -1; + + for (k => slot in this) { + if (slot.name != item) { + continue; + } + + if (slot.count < min) { + min = slot.count; + minSlot = k; + } + }; + + return minSlot == -1 ? null : minSlot; + } + + /** + Get all slots for an Item. + **/ + public function getSlotsForItems():Map> { + var rtn:Map> = new Map(); + + for (k => slot in this) { + if (!rtn.exists(slot.name)) { + rtn.set(slot.name, [k]); + continue; + } + + var value = rtn.get(slot.name); + value.push(k); + rtn.set(slot.name, value); + } + + return rtn; + } + + /** + Returns the first slot that contains this item. + **/ + public function findItemSlot(item:Item):Null { + for (k => slot in this) { + if (slot.name == item) { + return k; + } + } + + return null; + } +}