1

Compare commits

...

3 Commits

5 changed files with 214 additions and 37 deletions

View File

@ -0,0 +1,82 @@
local TurtleController = require("controller.turtle_controller")
local AudioController = require("controller.audio_controller")
---@class AudioTestingController
---@field controller TurtleController
---@field audio AudioController
local AudioTestingController = {}
AudioTestingController.__index = AudioTestingController
---@return AudioTestingController
function AudioTestingController:Create()
local t = {}
setmetatable(t, AudioTestingController)
-----------------------------------------------------------------------------------------------
-- Fields
-----------------------------------------------------------------------------------------------
t.controller = TurtleController:Create()
t.audio = AudioController:Create()
return t
end
-----------------------------------------------------------------------------------------------
-- Behavior Methods
-----------------------------------------------------------------------------------------------
function AudioTestingController:TestAudioWithoutMovement()
local function dancing()
for _ = 1, 256 do
self.controller:TurnRelative(1)
end
self.audio:StopPlaying()
end
parallel.waitForAll(dancing, self.audio:PlayAudioFactory("bangarang"))
end
function AudioTestingController:TestAudioWithMovement()
local function movement()
for _ = 1, 10 do
self.controller:MoveForward(10)
self.controller:MoveVertical(3)
self.controller:TurnRelative(2)
self.controller:MoveForward(10)
self.controller:MoveVertical(-3)
self.controller:TurnRelative(2)
end
self.audio:StopPlaying()
end
parallel.waitForAll(movement, self.audio:PlayAudioFactory("bangarang"))
end
-----------------------------------------------------------------------------------------------
-- Main Method
-----------------------------------------------------------------------------------------------
function AudioTestingController:Run()
self.controller:Configure()
self.controller:DisableMiningForward()
self.controller:DisableMiningAbove()
self.controller:DisableMiningBelow()
print("There are multiple tests available:")
print("1: Audio without movement")
print("2: Audio with movement")
local choice = 0
while choice < 1 or choice > 2 do
print("Choose a test by entering its number:")
choice = tonumber(io.read()) or 0
end
if choice == 1 then
self:TestAudioWithoutMovement()
elseif choice == 2 then
self:TestAudioWithMovement()
end
end
return AudioTestingController

View File

@ -246,7 +246,7 @@ function ExcavationController:Excavate()
-- Finish up
self.controller:MoveToPosition(0, 0, 0, self.controller.config.storage_direction)
self.controller:DropInventory()
self.controller:DropInventoryIntoChest()
self.controller:TurnToDirection(Direction.NORTH)
self.audio:StopPlaying()
end

View File

@ -102,15 +102,24 @@ function TurtleController:MoveForward(number_of_blocks, skip_unstocking, skip_re
-- Mine/Move
if self.mine_forward then
while not turtle.forward() do
if self:TestForBlock("minecraft:chest") then
error("Won't mine because a chest is in the way!")
end
turtle.dig()
end
elseif not turtle.forward() then
error("Turtle failed to move forward!")
end
if self.mine_above then
if self:TestForBlock("minecraft:chest", true, false) then
error("Won't mine because a chest is in the way!")
end
turtle.digUp()
end
if self.mine_below then
if self:TestForBlock("minecraft:chest", false, true) then
error("Won't mine because a chest is in the way!")
end
turtle.digDown()
end
@ -152,13 +161,15 @@ function TurtleController:MoveVertical(number_of_blocks, skip_unstocking, skip_r
self:UnstockIfFull()
end
-- Mine
-- Mine/Move
if mine_enabled then
mine_function()
end
-- Move
if not move_function() then
while not move_function() do
if self:TestForBlock("minecraft:chest", number_of_blocks > 0, number_of_blocks < 0) then
error("Won't mine because a chest is in the way!")
end
mine_function()
end
elseif not move_function() then
error("Turtle failed to move vertically!")
end
@ -189,7 +200,15 @@ function TurtleController:MoveToPosition(x, y, z, dir, skip_unstocking, skip_ref
-- Store the current position on the stack, so we can return using TurtleController:MoveBack()
self.last_positions:Push(Position:Copy(self.position))
-- Store mining config so we can restore it later
local mine_forward = self.mine_forward
local mine_above = self.mine_above
local mine_below = self.mine_below
-- EAST/WEST axis (do first to not interfere with chests)
self:EnableMiningForward()
self:DisableMiningAbove()
self:DisableMiningBelow()
if self.position.x > x then
self:TurnToDirection(Direction.WEST)
elseif self.position.x < x then
@ -206,11 +225,34 @@ function TurtleController:MoveToPosition(x, y, z, dir, skip_unstocking, skip_ref
self:MoveForward(math.abs(z - self.position.z), skip_unstocking, skip_refueling)
-- UP/DOWN axis
self:DisableMiningForward()
if y < self.position.y then
self:EnableMiningBelow()
elseif y > self.position.y then
self:EnableMiningAbove()
end
self:MoveVertical(y - self.position.y, skip_unstocking, skip_refueling)
-- Direction
self:TurnToDirection(dir or Direction.NORTH)
-- Restore mining config
if mine_forward then
self:EnableMiningForward()
else
self:DisableMiningForward()
end
if mine_above then
self:EnableMiningAbove()
else
self:DisableMiningAbove()
end
if mine_below then
self:EnableMiningBelow()
else
self:DisableMiningBelow()
end
-- Sanity check
if not (self.position.x == x and self.position.y == y and self.position.z == z and self.position.dir == dir) then
error("TurtleController:MoveToPosition failed to move to target position!")
@ -258,6 +300,37 @@ function TurtleController:MoveBack(skip_unstocking, skip_refueling)
end
end
-----------------------------------------------------------------------------------------------
-- Testing Methods
-----------------------------------------------------------------------------------------------
---@param block_name string
---@param above boolean | nil
---@param below boolean | nil
---@return boolean
function TurtleController:TestForBlock(block_name, above, below)
above = above or false
below = below or false
if above and below then
error("Can only test for blocks in one direction!")
end
local inspect_function = turtle.inspect
if above then
inspect_function = turtle.inspectUp
elseif below then
inspect_function = turtle.inspectDown
end
local has_block, block_data = inspect_function()
if not has_block then
return false
end
return block_data.name == block_name
end
-----------------------------------------------------------------------------------------------
-- Inventory Methods
-----------------------------------------------------------------------------------------------
@ -284,7 +357,11 @@ end
---@param slot number
---@param count number
---@return boolean
function TurtleController:SuckItem(slot, count)
function TurtleController:SuckItemFromChest(slot, count)
if not self:TestForBlock("minecraft:chest") then
error("Can't suck item: no chest!")
end
local previous_slot = turtle.getSelectedSlot()
turtle.select(slot or 1)
@ -298,7 +375,11 @@ end
---@param slot number
---@param count number
---@return boolean
function TurtleController:DropItem(slot, count)
function TurtleController:DropItemIntoChest(slot, count)
if not self:TestForBlock("minecraft:chest") then
error("Can't drop item: no chest!")
end
local previous_slot = turtle.getSelectedSlot()
turtle.select(slot or 1)
@ -309,7 +390,11 @@ function TurtleController:DropItem(slot, count)
return dropped
end
function TurtleController:DropInventory()
function TurtleController:DropInventoryIntoChest()
if not self:TestForBlock("minecraft:chest") then
error("Can't drop item: no chest!")
end
print("Dropping inventory into chest...")
for slot = 1, 16 do
@ -333,9 +418,11 @@ function TurtleController:UnstockIfFull(skip_inventory_check)
print("Turtle is unstocking...")
self:MoveToPosition(0, 0, 0, self.config.storage_direction, true, true)
self:DropInventory()
self:DropInventoryIntoChest()
self:RefuelIfEmpty()
self:TurnToDirection(Direction.NORTH)
self:MoveForward(1)
self:MoveBack(true, true)
end
@ -353,7 +440,7 @@ function TurtleController:RefuelIfEmpty(skip_fuel_check)
-- Clear our inventory into the storage chest
self:MoveToPosition(0, 0, 0, self.config.storage_direction, true, true)
self:DropInventory()
self:DropInventoryIntoChest()
-- Prepare refueling
self:TurnToDirection(self.config.fuel_direction)
@ -372,13 +459,15 @@ function TurtleController:RefuelIfEmpty(skip_fuel_check)
-- Refuel until we hit the refuel_amount
local before_level = turtle.getFuelLevel()
repeat
if not self:SuckItem(1, 1) then
if not self:SuckItemFromChest(1, 1) then
error("Failed to suck fuel out of fuel chest!")
end
turtle.refuel()
until turtle.getFuelLevel() >= target_fuel_level
local after_level = turtle.getFuelLevel()
self:TurnToDirection(Direction.NORTH)
self:MoveForward(1)
self:MoveBack(true, true)
print(

View File

@ -1,15 +1,15 @@
local Direction = require("lib.direction")
local TurtleController = require("controller.turtle_controller")
---@class TestingController
---@class TurtleTestingController
---@field controller TurtleController
local TestingController = {}
TestingController.__index = TestingController
local TurtleTestingController = {}
TurtleTestingController.__index = TurtleTestingController
---@return TestingController
function TestingController:Create()
---@return TurtleTestingController
function TurtleTestingController:Create()
local t = {}
setmetatable(t, TestingController)
setmetatable(t, TurtleTestingController)
t.controller = TurtleController:Create()
@ -20,7 +20,7 @@ end
-- Behavior Methods
-----------------------------------------------------------------------------------------------
function TestingController:TestRelativeMovementWithRelativeRotation()
function TurtleTestingController:TestRelativeMovementWithRelativeRotation()
print("Testing relative movement with relative rotation...")
-- N: BackCenter (Center)
@ -50,7 +50,7 @@ function TestingController:TestRelativeMovementWithRelativeRotation()
_ = io.read()
end
function TestingController:TestRelativeMovementWithAbsoluteRotation()
function TurtleTestingController:TestRelativeMovementWithAbsoluteRotation()
print("Testing relative movement with absolute rotation...")
-- N: BackCenter (Center)
@ -80,7 +80,7 @@ function TestingController:TestRelativeMovementWithAbsoluteRotation()
_ = io.read()
end
function TestingController:TestAbsoluteMovementWithoutStack()
function TurtleTestingController:TestAbsoluteMovementWithoutStack()
print("Testing absolute movement without stack...")
-- N: BackCenter (Center)
@ -104,7 +104,7 @@ function TestingController:TestAbsoluteMovementWithoutStack()
_ = io.read()
end
function TestingController:TestAbsoluteMovementWithStack()
function TurtleTestingController:TestAbsoluteMovementWithStack()
print("Testing absolute movement with stack...")
-- N: BotCenter (Center)
@ -126,7 +126,7 @@ function TestingController:TestAbsoluteMovementWithStack()
_ = io.read()
end
function TestingController:TestUnstocking()
function TurtleTestingController:TestUnstocking()
print("Testing inventory unloading...")
self.controller:MoveToPosition(3, 0, 3, Direction.WEST)
@ -143,7 +143,7 @@ function TestingController:TestUnstocking()
_ = io.read()
end
function TestingController:TestRefueling()
function TurtleTestingController:TestRefueling()
print("Testing refueling...")
self.controller:MoveToPosition(3, 0, 3, Direction.WEST)
@ -164,7 +164,7 @@ end
-- Main Method
-----------------------------------------------------------------------------------------------
function TestingController:Run()
function TurtleTestingController:Run()
self.controller:Configure()
self.controller:DisableMiningForward()
self.controller:DisableMiningAbove()
@ -217,4 +217,4 @@ function TestingController:Run()
end
end
return TestingController
return TurtleTestingController

View File

@ -1,17 +1,20 @@
local TestingController = require("controller.testing_controller")
local TurtleTestingController = require("controller.turtle_testing_controller")
local AudioTestingController = require("controller.audio_testing_controller")
local ExcavationController = require("controller.excavation_controller")
local AudioController = require("controller.audio_controller")
local controllers = {
TestingController:Create(),
TurtleTestingController:Create(),
AudioTestingController:Create(),
ExcavationController:Create(),
AudioController:Create(),
}
print("Multiple controllers are available:")
print("1: Testing Mode")
print("2: Volume Excavation")
print("3: Play Bangarang")
print("1: Turtle Testing Mode")
print("2: Audio Testing Mode")
print("3: Volume Excavation")
print("4: Play Bangarang")
local choice = 0
while choice < 1 or choice > #controllers do
@ -21,10 +24,13 @@ end
controllers[choice]:Run()
-- TODO: StackOverflow once the inventory is full, unstocking doesn't work...
-- Is the InventoryFull check wrong?
-- TODO: Test if there's a chest when dropping/sucking/mining (don't mine chests!)
-- TODO: When refueling but chest is missing, wait there until the user puts a chest with fuel
-- TODO: Improve error handling: Don't abort the program in all cases,
-- but wait until the user fixes the issue (e.g. places a chest)
-- TODO: Add shortcuts for the volume excavation:
-- - Tunnel forward 3x2 or 3x3 with specified length
-- - Excavate downwards (quarry) in a square, specify side length
-- TODO: Add controller to build rooms with walls of a specified material
-- TODO: Support specifying the mining height
-- TODO: Add a stair building mode (specify side length, min 2x2)
-- TODO: Add configurable trash_list with items that won't be picked up
-- TODO: Add a speaker to the turtle (listen to music while mining)