Moved item stuff to itemscript.

This commit is contained in:
Andrew Lalis 2022-12-17 16:15:34 +01:00
parent 26933d17a0
commit 625f671821
3 changed files with 293 additions and 0 deletions

10
install.lua Normal file
View File

@ -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")

89
itemscript.lua Normal file
View File

@ -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

194
movescript.lua Normal file
View File

@ -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