refactored InvManager and State
This commit is contained in:
parent
5c71ab1c30
commit
9353ccba8a
@ -9,123 +9,28 @@ import kernel.turtle.Turtle;
|
|||||||
using Lambda;
|
using Lambda;
|
||||||
using tink.CoreApi;
|
using tink.CoreApi;
|
||||||
|
|
||||||
typedef InvState = Map<TurtleSlot, {count:Int, name:Item, max:Int}>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A wrapper for the native turtle inventory functions. Adds usefullt helper functions.
|
A wrapper for the native turtle inventory functions. Adds usefullt helper functions.
|
||||||
**/
|
**/
|
||||||
class InvManager {
|
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<Item, Int> {
|
|
||||||
var invState = getInvState();
|
|
||||||
var rtn:Map<Item, Int> = 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<TurtleSlot> {
|
|
||||||
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<Noise, String> {
|
public static function place(item:Item, dir:InteractDirections):Outcome<Noise, String> {
|
||||||
var invState = getInvState();
|
var invState = new InvState();
|
||||||
var slot = getSlotWithMinCountForItem(item, invState);
|
var slot = invState.getSlotWithMinCountForItem(item);
|
||||||
if (slot == null) {
|
if (slot == null) {
|
||||||
return Failure("Item not in inventory");
|
return Failure("Item not in inventory");
|
||||||
}
|
}
|
||||||
|
|
||||||
return placeSlot(slot, dir);
|
Turtle.selectSlot(slot);
|
||||||
}
|
|
||||||
|
|
||||||
private static function placeSlot(slot:TurtleSlot, dir:InteractDirections):Outcome<Noise, String> {
|
|
||||||
Turtle.selectSlot(slot); // TODO: handle error
|
|
||||||
return Turtle.place(dir);
|
return Turtle.place(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function getSlotsForItems(invState:InvState):Map<Item, Array<TurtleSlot>> {
|
|
||||||
var rtn:Map<Item, Array<TurtleSlot>> = 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<TurtleSlot> {
|
|
||||||
var invState = getInvState();
|
|
||||||
|
|
||||||
for (k => slot in invState) {
|
|
||||||
if (slot.name == item) {
|
|
||||||
return k;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Cleans up turtle inventory. Moves items together.
|
Cleans up turtle inventory. Moves items together.
|
||||||
This should be run in a turtle thread.
|
This should be run in a turtle thread.
|
||||||
**/
|
**/
|
||||||
public static function defrag() {
|
public static function defrag() {
|
||||||
var invState = getInvState();
|
var invState = new InvState();
|
||||||
var items = getSlotsForItems(invState);
|
var items = invState.getSlotsForItems();
|
||||||
|
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
defragItem(invState, item);
|
defragItem(invState, item);
|
||||||
@ -198,7 +103,8 @@ class InvManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static function equipTool(item:Item, side:ToolSide):Outcome<TurtleSlot, String> {
|
public static function equipTool(item:Item, side:ToolSide):Outcome<TurtleSlot, String> {
|
||||||
var toolSlot = findItemSlot(item);
|
var invState = new InvState();
|
||||||
|
var toolSlot = invState.findItemSlot(item);
|
||||||
|
|
||||||
if (toolSlot == null) {
|
if (toolSlot == null) {
|
||||||
return Failure("Item not found");
|
return Failure("Item not found");
|
||||||
|
99
src/lib/turtle/InvState.hx
Normal file
99
src/lib/turtle/InvState.hx
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
package lib.turtle;
|
||||||
|
|
||||||
|
import kernel.turtle.Turtle;
|
||||||
|
import kernel.turtle.TurtleSlot;
|
||||||
|
|
||||||
|
@:forward(get, set, iterator, keyValueIterator)
|
||||||
|
abstract InvState(Map<TurtleSlot, {count:Int, name:Item, max:Int}>) {
|
||||||
|
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<Item, Int> {
|
||||||
|
var rtn:Map<Item, Int> = 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<TurtleSlot> {
|
||||||
|
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<Item, Array<TurtleSlot>> {
|
||||||
|
var rtn:Map<Item, Array<TurtleSlot>> = 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<TurtleSlot> {
|
||||||
|
for (k => slot in this) {
|
||||||
|
if (slot.name == item) {
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user