Moved item stuff to itemscript.
This commit is contained in:
parent
26933d17a0
commit
625f671821
|
@ -0,0 +1,10 @@
|
||||||
|
--[[
|
||||||
|
Installation script for installing all libraries.
|
||||||
|
|
||||||
|
Run `wget run https://github.com/andrewlalis/movescript/blob/main/install.lua`
|
||||||
|
to run the installer on your device.
|
||||||
|
]]--
|
||||||
|
|
||||||
|
BASE_URL = "https://github.com/andrewlalis/movescript/blob/main"
|
||||||
|
|
||||||
|
shell.run("wget " .. BASE_URL .. "/movescript.lua")
|
|
@ -0,0 +1,89 @@
|
||||||
|
--[[
|
||||||
|
Itemscript - A simplified set of methods for item manipulation.
|
||||||
|
|
||||||
|
Author: Andrew Lalis <andrewlalisofficial@gmail.com>
|
||||||
|
|
||||||
|
|
||||||
|
]]--
|
||||||
|
local t = turtle
|
||||||
|
|
||||||
|
-- The itemscript module. Functions defined within this table are exported.
|
||||||
|
local itemscript = {}
|
||||||
|
|
||||||
|
local function itemStackMatches(itemStack, name, fuzzy)
|
||||||
|
return itemStack ~= nil and
|
||||||
|
(
|
||||||
|
(not fuzzy and itemStack.name == name) or
|
||||||
|
string.find(itemStack.name, name)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Gets the total number of items of a certain type in the turtle's inventory.
|
||||||
|
-- If fuzzy is set as true, then it'll match substrings matching the given name.
|
||||||
|
function itemscript.totalCount(name, fuzzy)
|
||||||
|
fuzzy = fuzzy or false
|
||||||
|
local count = 0
|
||||||
|
for i = 1, 16 do
|
||||||
|
local item = t.getItemDetail(i)
|
||||||
|
if itemStackMatches(item, name, fuzzy) then
|
||||||
|
count = count + item.count
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return count
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Selects a slot containing at least one of the given item type.
|
||||||
|
-- Returns a boolean indicating whether we could find and select the item.
|
||||||
|
function itemscript.select(name, fuzzy)
|
||||||
|
fuzzy = fuzzy or false
|
||||||
|
for i = 1, 16 do
|
||||||
|
local item = t.getItemDetail(i)
|
||||||
|
if itemStackMatches(item, name, fuzzy) then
|
||||||
|
t.select(i)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local function itemMatchesFilter(item, name, fuzzy)
|
||||||
|
fuzzy = fuzzy or false
|
||||||
|
return (not fuzzy and item.name == name) or string.find(item.name, name)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function itemNotMatchesFilter(item, name, fuzzy)
|
||||||
|
return not itemMatchesFilter(item, name, fuzzy)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function dropFiltered(name, fuzzy, dropFunction, filterFunction)
|
||||||
|
for i = 1, 16 do
|
||||||
|
local item = t.getItemDetail(i)
|
||||||
|
if filterFunction(item, name, fuzzy) then
|
||||||
|
t.select(i)
|
||||||
|
dropFunction()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function itemscript.dropAll(name, fuzzy)
|
||||||
|
dropFiltered(name, fuzzy or false, t.drop, itemMatchesFilter)
|
||||||
|
end
|
||||||
|
|
||||||
|
function itemscript.dropAllDown(name, fuzzy)
|
||||||
|
dropFiltered(name, fuzzy or false, t.dropDown, itemMatchesFilter)
|
||||||
|
end
|
||||||
|
|
||||||
|
function itemscript.dropAllUp(name, fuzzy)
|
||||||
|
dropFiltered(name, fuzzy or false, t.dropDown, itemMatchesFilter)
|
||||||
|
end
|
||||||
|
|
||||||
|
function itemscript.dropAllExcept(name, fuzzy)
|
||||||
|
dropFiltered(name, fuzzy or false, t.drop, itemMatchesFilter)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Cleans up the turtle's inventory by compacting all stacks of items.
|
||||||
|
function itemscript.organize()
|
||||||
|
error("Not yet implemented.")
|
||||||
|
end
|
||||||
|
|
||||||
|
return itemscript
|
|
@ -0,0 +1,194 @@
|
||||||
|
--[[
|
||||||
|
Movescript - A simplified robot script for ComputerCraft.
|
||||||
|
|
||||||
|
Author: Andrew Lalis <andrewlalisofficial@gmail.com>
|
||||||
|
|
||||||
|
Movescript provides a simpler, conciser way to program "turtles" (robots), so
|
||||||
|
that you don't need to get tired of typing "turtle.forward()" over and over.
|
||||||
|
|
||||||
|
]]--
|
||||||
|
local t = turtle
|
||||||
|
|
||||||
|
-- The movescript module. Functions defined within this table are exported.
|
||||||
|
local movescript = {}
|
||||||
|
|
||||||
|
local function debug(msg, settings)
|
||||||
|
if settings and settings.debug then
|
||||||
|
print("[MS] " .. msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Helper function for turtle to dig backwards.
|
||||||
|
function t.digBack(side)
|
||||||
|
t.turnRight()
|
||||||
|
t.turnRight()
|
||||||
|
t.dig(side)
|
||||||
|
t.turnRight()
|
||||||
|
t.turnRight()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Helper function for turtle to detect backwards.
|
||||||
|
function t.detectBack()
|
||||||
|
t.turnRight()
|
||||||
|
t.turnRight()
|
||||||
|
local result = t.detect()
|
||||||
|
t.turnRight()
|
||||||
|
t.turnRight()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
-- The default settings to apply to any robot movement, if none are specified.
|
||||||
|
local defaultMovementSettings = {
|
||||||
|
safe = true,
|
||||||
|
destructive = false,
|
||||||
|
fuels = {"minecraft:coal", "minecraft:charcoal"}
|
||||||
|
}
|
||||||
|
|
||||||
|
local function goDirection(dirFunction, digFunction, detectFunction, settings)
|
||||||
|
settings = settings or defaultMovementSettings
|
||||||
|
safe = settings.safe or defaultMovementSettings.safe
|
||||||
|
destructive = settings.destructive or defaultMovementSettings.destructive
|
||||||
|
local success = dirFunction()
|
||||||
|
if not safe then return end
|
||||||
|
while not success do
|
||||||
|
debug("Unable to move.", settings)
|
||||||
|
if destructive and detectFunction() then
|
||||||
|
debug("Detected a block in the way; attempting to remove it.", settings)
|
||||||
|
digFunction()
|
||||||
|
end
|
||||||
|
success = dirFunction()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function goUp(settings)
|
||||||
|
debug("Moving up.", settings)
|
||||||
|
goDirection(t.up, t.digUp, t.detectUp, settings)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function goDown(settings)
|
||||||
|
debug("Moving down.", settings)
|
||||||
|
goDirection(t.down, t.digDown, t.detectDown, settings)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function goForward(settings)
|
||||||
|
debug("Moving forward.", settings)
|
||||||
|
goDirection(t.forward, t.dig, t.detect, settings)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function goBack(settings)
|
||||||
|
debug("Moving back.", settings)
|
||||||
|
goDirection(t.back, t.digBack, t.detectBack, settings)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function goRight(settings)
|
||||||
|
debug("Turning right.", settings)
|
||||||
|
t.turnRight()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function goLeft(settings)
|
||||||
|
debug("Turning left.", settings)
|
||||||
|
t.turnLeft()
|
||||||
|
end
|
||||||
|
|
||||||
|
local actionMap = {
|
||||||
|
["U"] = {f = goUp, needsFuel = true},
|
||||||
|
["D"] = {f = goDown, needsFuel = true},
|
||||||
|
["L"] = {f = goLeft, needsFuel = false},
|
||||||
|
["R"] = {f = goRight, needsFuel = false},
|
||||||
|
["F"] = {f = goForward, needsFuel = true},
|
||||||
|
["B"] = {f = goBack, needsFuel = true},
|
||||||
|
["P"] = {f = t.place, needsFuel = false},
|
||||||
|
["Pu"] = {f = t.placeUp, needsFuel = false},
|
||||||
|
["Pd"] = {f = t.placeDown, needsFuel = false},
|
||||||
|
["A"] = {f = t.attack, needsFuel = false},
|
||||||
|
["Au"] = {f = t.attackUp, needsFuel = false},
|
||||||
|
["Ad"] = {f = t.attackDown, needsFuel = false}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Tries to refuel the turtle from all slots that contain a valid fuel.
|
||||||
|
-- Returns a boolean indicating if at least one piece of fuel was consumed.
|
||||||
|
local function refuelAll(settings)
|
||||||
|
debug("Refueling...", settings)
|
||||||
|
local fuels = settings.fuels or defaultMovementSettings.fuels
|
||||||
|
local refueled = false
|
||||||
|
for slot = 1, 16 do
|
||||||
|
local item = t.getItemDetail(slot)
|
||||||
|
for _, fuelName in pairs(fuels) do
|
||||||
|
if item.name == fuelName then
|
||||||
|
t.select(i)
|
||||||
|
if t.refuel(item.count) then refueled = true end
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return refueled
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Blocks until the turtle's fuel level is at least at the required level.
|
||||||
|
local function refuelToAtLeast(requiredLevel, settings)
|
||||||
|
refuelAll(settings)
|
||||||
|
while t.getFuelLevel < requiredLevel do
|
||||||
|
print(
|
||||||
|
"[MS] Fuel level is too low. Level: " .. t.getFuelLevel() .. ". Required: " .. requiredLevel ..
|
||||||
|
". Please add some of the following fuels:"
|
||||||
|
)
|
||||||
|
local fuels = settings.fuels or defaultMovementSettings.fuels
|
||||||
|
for _, fuelName in pairs(fuels) do
|
||||||
|
print(" - " .. fuelName)
|
||||||
|
end
|
||||||
|
local fuelUpdated = false
|
||||||
|
while not fuelUpdated do
|
||||||
|
os.pullEvent("turtle_inventory")
|
||||||
|
fuelUpdated = refuelAll()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Executes a single instruction. An instruction is a table with an "action"
|
||||||
|
-- and some attributes, such as if it needs fuel or not.
|
||||||
|
local function executeInstruction(instruction, settings)
|
||||||
|
local action = actionMap[instruction.action]
|
||||||
|
if action then
|
||||||
|
debug("Executing action \"" .. instruction.action .. "\" " .. instruction.count .. " times.", settings)
|
||||||
|
if action.needsFuel and instruction.count > t.getFuelLevel() then
|
||||||
|
local fuelRequired = instruction.count
|
||||||
|
refuelToAtLeast(fuelRequired, settings)
|
||||||
|
end
|
||||||
|
for i = 1, instruction.count do action.f() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Parses a movescript script into a series of instruction tables.
|
||||||
|
local function parseScript(script, settings)
|
||||||
|
local instructions = {}
|
||||||
|
for instruction in string.gfind(script, "%W*(%d*%u%l*)%W*") do
|
||||||
|
local countIdx, countIdxEnd = string.find(instruction, "%d+")
|
||||||
|
local actionIdx, actionIdxEnd = string.find(instruction, "%u%l*")
|
||||||
|
local count = 1
|
||||||
|
if countIdx ~= nil then
|
||||||
|
count = tonumber(string.sub(instruction, countIdx, countIdxEnd))
|
||||||
|
end
|
||||||
|
local action = string.sub(instruction, actionIdx, actionIdxEnd)
|
||||||
|
if count < 1 or count > t.getFuelLimit() then
|
||||||
|
error("Instruction at index " .. actionIdx .. " has an invalid count of " .. count .. ". It should be >= 1 and <= " .. t.getFuelLimit())
|
||||||
|
end
|
||||||
|
if actionMap[action] == nil then
|
||||||
|
error("Instruction at index " .. actionIdx .. ", \"" .. action .. "\", does not refer to a valid action.")
|
||||||
|
end
|
||||||
|
table.insert(instructions, {action = action, count = count})
|
||||||
|
debug("Parsed instruction: " .. instruction, settings)
|
||||||
|
end
|
||||||
|
return instructions
|
||||||
|
end
|
||||||
|
|
||||||
|
function movescript.run(script, settings)
|
||||||
|
settings = settings or defaultMovementSettings
|
||||||
|
script = script or ""
|
||||||
|
debug("Executing script: " .. script, settings)
|
||||||
|
local instructions = parseScript(script, settings)
|
||||||
|
for idx, instruction in pairs(instructions) do
|
||||||
|
executeInstruction(instruction, settings)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return movescript
|
Loading…
Reference in New Issue