jille_Jr icon

CC: Treefarm - item.lua

jille_Jr | PRO | 06/17/14 08:18:32 PM UTC | 0 ⭐ | 518 👁️ | Never ⏰ | []
Lua |

6.32 KB

|

None

|

0 👍

/

0 👎

 
inventory = {}
types = {
    unknown = "unknown",
    dirt = "dirt",
    grass = "dirt",
    sapling = "sapling",
    log = "wood",
    wood = "wood",
    dropoff = "dropoff", --not actual item type, but can be refered to
}
-- position for each type
-- while standing at target location facing desired direction
-- turtle should be able to do a turtle.suck() to grab the material
-- if dir=up suckUp() if dir=down suckDown()
position = {}
 
-- if you have a small tunnel towards your storage for the turtle
-- addStoragePathCheckpoint(x,y,z) to add enterance
-- ^ can be used multiple times if you have a complicated path
-- turtle will follow the path in revese when it exits
storageEnterancePath = {}
 
local differenceRecord = {}
 
function update()
    for slot = 1,16 do
        local oldType = nil
        if type(inventory[slot])=="table" then oldType=inventory[slot].type end
        inventory[slot] = {
            type = oldType or types.unknown,
            qty = turtle.getItemCount(slot),
        }
        if inventory[slot].qty==0 then
            inventory[slot].type = nil
        end
    end
end
 
-- gets all global variables
function init( global )
    update()
    setfenv(1,global)
end
 
function recordDifference()
    differenceRecord = {}
    for slot=1,16 do
        differenceRecord[slot] = {
            type = inventory[slot].type,
            qty = inventory[slot].qty,
        }
    end
end
 
function getDifference()
    local difference = {}
    update()
    for slot=1,16 do
        local qtyDifference = inventory[slot].qty - differenceRecord[slot].qty
        if qtyDifference~=0 or inventory[slot].type~=differenceRecord[slot].type then
            difference[slot] = {}
            difference[slot].qty = qtyDifference
            difference[slot].type = differenceRecord[slot].type
 
            if inventory[slot].type~=differenceRecord[slot].type then
                difference[slot].oldType = differenceRecord[slot].type
            end
        end
    end
    return difference
end
 
function setItemAccess( item,x,y,z,dir )
    position[item] = {x=x,y=y,z=z,dir=dir}
end
 
function getItemAccess( item )
    return position[item].x,position[item].y,position[item].z,position[item].dir
end
 
function addStoragePathCheckpoint( x,y,z )
    storageEnterancePath[#storageEnterancePath+1] = {x=x,y=y,z=z}
end
 
function getStoragePathCheckpoint( step )
    if type(storageEnterancePath[step])=="table" then
        return (storageEnterancePath[step].x or _),(storageEnterancePath[step].y or _),(storageEnterancePath[step].z or _)
    end
end
 
function resetStoragePath()
    storageEnterancePath = {}
end
 
-- reverse = boolean
function followStoragePath( reverse )
    if type(reverse)~="boolean" then reverse = false end
 
    local start = 1
    local stop = #storageEnterancePath
    if reverse then start=stop stop=1 end
 
    for step = start,stop,mult(stop-start) do
        gps.goto(getStoragePathCheckpoint(step))
    end
end
 
function getItemCount( item )
    update()
    local count = 0
    for slot = 1,16 do
        if inventory[slot].type == item then
            count = count + inventory[slot].qty
        end
    end
    return count
end
 
-- gotoStorageRoom = (boolean) wether or not it should follow the storage path
function dropoff( gotoStorageRoom )
    if type(gotoStorageRoom)~="boolean" then gotoStorageRoom = false end
 
    -- dropoff must have a location
    local x,y,z,dir = getItemAccess(types.dropoff)
    if type(x)~="number" or type(y)~="number"
    or type(z)~="number" or type(dir)~="string" then
        return false
    end
 
    if gotoStorageRoom then
        followStoragePath()
    end
 
    gps.goto(x,y,z,dir)
 
    for slot=1,16 do
        local count = turtle.getItemCount(slot)
        while count~=0 do
            turtle.select(slot)
            if dir==gps.up then
                turtle.dropUp(count)
            elseif dir==gps.down then
                turtle.dropDown(count)
            else
                turtle.drop(count)
            end
            count = turtle.getItemCount(slot)
        end
    end
 
    -- exit the storage room
    if gotoStorageRoom then
        followStoragePath(true)
    end
end
 
-- tries to get item from storage canceles if it has enough
-- returns true on success and false when it fails for some reason
-- noEnterancePath=true if you dont want it to go through the storage enterance path
function getItem( item,minQty,noEnterancePath )
    if type(minQty)~="number" then minQty=64 end
    if type(noEnterancePath)~="boolean" then noEnterancePath=false end
 
    -- count quantity already in inventory
    local qtyRequired = minQty - getItemCount(item)
    if qtyRequired < 1 then
        -- already got enough of target item
        return true
    end
 
    -- item must be obtainable
    local x,y,z,dir = getItemAccess(item)
    if type(x)~="number" or type(y)~="number"
    or type(z)~="number" or type(dir)~="string" then
        return false
    end
 
    if not noEnterancePath then
        followStoragePath()
    end
 
    -- check if inv is full
    update()
    local invFull = true
    for slot=1,16 do
        if inventory[slot].qty == 0 then
            invFull = false
            break
        end
    end
 
    if invFull then
        dropoff(false)
    end
 
    gps.goto(x,y,z,dir)
 
    local qtyInInv-- number
    repeat
        recordDifference()
 
        if dir == gps.up then
            turtle.suckUp()
        elseif dir == gps.down then
            turtle.suckDown()
        else
            turtle.suck()
        end
        
        -- check how many slots changed when you sucked for items
        local diff = getDifference()
        local slotsChanged = 0
        for slot,item in pairs(diff) do
            slotsChanged = slotsChanged + 1
        end
 
        if slotsChanged == 0 then
            -- didn't obtain anything when trying to get items
            -- gonna have to loop through again and again
            --break
        elseif slotsChanged > 1 then
            -- more than one slot changed, might be 'cause of player interaction
            -- go empty out and try again just so we know for sure we can keep track of the item
            dropoff(false)
            gps.goto(x,y,z,dir)
        elseif slotsChanged == 1 then
            -- one slot changed, record it, gotta keep track of it
            for slot in pairs(diff) do
                inventory[slot].type = item
            end
        end
 
        qtyInInv = getItemCount(item)
    until qtyInInv >= qtyRequired
 
    if not noEnterancePath then
        followStoragePath(true)
    end
 
    return true
end
 
-- example input
-- t = { "dirt", "sapling" } minQty = 64: gets 64 dirt and 64 saplings
function getItems( t,minQty )
    for num,item in ipairs(t) do
        if num == 1 then
            followStoragePath(false)
        end
        getItem(item,minQty,true)
        if num == #t then
            followStoragePath(true)
        end
    end
end
 
function select( item )
    for slot=1,16 do
        if inventory[slot].type == item then
            turtle.select(slot)
            return true
        end
    end
    return false
end

Comments