added turtle defrag
This commit is contained in:
parent
3fce8d515a
commit
6170fdd0d3
@ -1,7 +1,5 @@
|
||||
package lib.turtle;
|
||||
|
||||
import kernel.KernelEvents;
|
||||
import tink.CoreApi.Outcome;
|
||||
import kernel.log.Log;
|
||||
import kernel.turtle.Types.TurtleSlot;
|
||||
import kernel.turtle.Types.InteractDirections;
|
||||
@ -20,7 +18,7 @@ class InvManager {
|
||||
|
||||
private static function getInvState() {
|
||||
var invState:InvState = new Map();
|
||||
for (i in 0...Turtle.MAX_SLOTS - 1) {
|
||||
for (i in 0...Turtle.MAX_SLOTS) {
|
||||
var detail = Turtle.getItemDetail(i);
|
||||
var spaceLeft = Turtle.getItemSpace(i);
|
||||
|
||||
@ -87,4 +85,90 @@ class InvManager {
|
||||
Turtle.selectSlot(slot); // TODO: handle error
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
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);
|
||||
|
||||
for (item in items) {
|
||||
defragItem(invState, item);
|
||||
}
|
||||
}
|
||||
|
||||
private static function defragItem(invState:InvState, slots:Array<TurtleSlot>) {
|
||||
// Sort slots by items inside.
|
||||
slots.sort((a, b) -> {
|
||||
return invState.get(a).count - invState.get(b).count;
|
||||
});
|
||||
|
||||
var maxInSlot = invState.get(slots[0]).max;
|
||||
|
||||
// Loop from both sides. Move the slots with the lowest count into the fullest.
|
||||
var topIndex = slots.length - 1;
|
||||
|
||||
for (k => slot in slots) {
|
||||
if (topIndex <= k) {
|
||||
return;
|
||||
}
|
||||
|
||||
var count = invState.get(slot).count;
|
||||
|
||||
if (count == maxInSlot) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (topIndex <= k) {
|
||||
return;
|
||||
}
|
||||
|
||||
var topCount = invState.get(slots[topIndex]).count;
|
||||
var spaceInTop = maxInSlot - topCount;
|
||||
|
||||
if (spaceInTop == 0) {
|
||||
topIndex--;
|
||||
continue;
|
||||
}
|
||||
|
||||
var transferCount = MathI.min(count, spaceInTop);
|
||||
if (!Turtle.transfer(slot, slots[topIndex], transferCount).isSuccess()) {
|
||||
Log.error("Failed to transfer items");
|
||||
}
|
||||
|
||||
// Update invState
|
||||
var topState = invState.get(slots[topIndex]);
|
||||
topState.count += transferCount;
|
||||
invState.set(topIndex, topState);
|
||||
|
||||
var botState = invState.get(slot);
|
||||
botState.count -= transferCount;
|
||||
invState.set(slot, botState);
|
||||
|
||||
if (count - transferCount <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user