diff --git a/.vscode/settings.json b/.vscode/settings.json index fbf8b76..aef4dea 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,8 @@ "Lua.diagnostics.globals": [ "printError", "turtle", - "shell" + "shell", + "peripheral", + "parallel" ] } \ No newline at end of file diff --git a/audio/bangarang.dfpwm b/audio/bangarang.dfpwm new file mode 100644 index 0000000..d116495 Binary files /dev/null and b/audio/bangarang.dfpwm differ diff --git a/controller/audio_controller.lua b/controller/audio_controller.lua new file mode 100644 index 0000000..12a6e42 --- /dev/null +++ b/controller/audio_controller.lua @@ -0,0 +1,96 @@ +local dfpwm = require("cc.audio.dfpwm") +local Direction = require("lib.direction") + +---@alias AudioControllerConfig {buffer_length_seconds: number} + +---@class AudioController +---@field config AudioControllerConfig +---@field play boolean +local AudioController = {} +AudioController.__index = AudioController + + +---@return AudioController +function AudioController:Create() + local t = {} + setmetatable(t, AudioController) + + + ----------------------------------------------------------------------------------------------- + -- Fields + ----------------------------------------------------------------------------------------------- + t.config = { + buffer_length_seconds = 1 + } + t.play = false + + + return t +end + + +----------------------------------------------------------------------------------------------- +-- Audio Methods +----------------------------------------------------------------------------------------------- + + +function AudioController:PlayAudio(filename) + self.play = true + + local decoder = dfpwm.make_decoder() + while self.play do + for chunk in io.lines(("audio/%s.dfpwm"):format(filename), self.config.buffer_length_seconds * 1024) do + if not self.play then + break + end + + local buffer = decoder(chunk) + + while not self:GetSpeaker().playAudio(buffer) do + ---@diagnostic disable-next-line: undefined-field + os.pullEvent("speaker_audio_empty") + end + end + end +end + + +function AudioController:PlayAudioFactory(filename) + local function play() + self:PlayAudio(filename) + end + + return play +end + + +----------------------------------------------------------------------------------------------- +-- Management Methods +----------------------------------------------------------------------------------------------- + + +---@return table | nil +function AudioController:GetSpeaker() + return peripheral.find("speaker") +end + + +function AudioController:StopPlaying() + self.play = false + self:GetSpeaker().stop() +end + + +----------------------------------------------------------------------------------------------- +-- Main Method +----------------------------------------------------------------------------------------------- + + +function AudioController:Run() + -- self:Configure() + + self:PlayAudio("bangarang") +end + + +return AudioController \ No newline at end of file diff --git a/controller/excavation_controller.lua b/controller/excavation_controller.lua index 1339b74..9b7c546 100644 --- a/controller/excavation_controller.lua +++ b/controller/excavation_controller.lua @@ -1,10 +1,12 @@ local Direction = require("lib.direction") local TurtleController = require("controller.turtle_controller") +local AudioController = require("controller.audio_controller") ---@alias ExcavationControllerConfig {slice_length: number, slice_height: number, center_slice_width: number, slice_width: number, slice_padding: number, slices_left: number, slices_right: number} ---@class ExcavationController ---@field controller TurtleController +---@field audio AudioController ---@field config ExcavationControllerConfig local ExcavationController = {} ExcavationController.__index = ExcavationController @@ -22,6 +24,7 @@ function ExcavationController:Create() t.controller = TurtleController:Create() + t.audio = AudioController:Create() t.config = { slice_length = 0, slice_height = 0, @@ -176,80 +179,85 @@ function ExcavationController:Excavate() self:Excavate_WxHxL(true) self.controller:MoveBack() -- (0, 0, 1) - -- Move to right slices starting location - local padded_width_right = self.config.slices_right * (self.config.slice_width + self.config.slice_padding) - self.controller:StorePosition() - self.controller:TurnToDirection(Direction.EAST) - self.controller:EnableMiningForward() - self.controller:EnableMiningAbove() - self.controller:MoveForward(center_width_right + padded_width_right) - self.controller:DisableMiningForward() - self.controller:DisableMiningAbove() - self.controller:TurnToDirection(Direction.NORTH) + if self.config.slices_right > 0 then + -- Move to right slices starting location + local padded_width_right = self.config.slices_right * (self.config.slice_width + self.config.slice_padding) + self.controller:StorePosition() + self.controller:TurnToDirection(Direction.EAST) + self.controller:EnableMiningForward() + self.controller:EnableMiningAbove() + self.controller:MoveForward(center_width_right + padded_width_right) + self.controller:DisableMiningForward() + self.controller:DisableMiningAbove() + self.controller:TurnToDirection(Direction.NORTH) - -- Excavate right slices - print("Excavating right slices") - for i = 1,self.config.slices_right do - self:Excavate_WxHxL() + -- Excavate right slices + print("Excavating right slices") + for i = 1,self.config.slices_right do + self:Excavate_WxHxL() - if i == self.config.slices_right then - break + if i == self.config.slices_right then + break + end + + -- Move to the next slice + self.controller:TurnToDirection(Direction.WEST) + self.controller:EnableMiningForward() + self.controller:EnableMiningAbove() + self.controller:MoveForward(self.config.slice_width + self.config.slice_padding) + self.controller:DisableMiningForward() + self.controller:DisableMiningAbove() + self.controller:TurnToDirection(Direction.NORTH) end - - -- Move to the next slice - self.controller:TurnToDirection(Direction.WEST) - self.controller:EnableMiningForward() - self.controller:EnableMiningAbove() - self.controller:MoveForward(self.config.slice_width + self.config.slice_padding) - self.controller:DisableMiningForward() - self.controller:DisableMiningAbove() - self.controller:TurnToDirection(Direction.NORTH) + self.controller:MoveBack() -- (0, 0, 1) end - self.controller:MoveBack() -- (0, 0, 1) - -- Move to left slices starting location - local center_width_left = self.config.center_slice_width - center_width_right - self.controller:StorePosition() - self.controller:TurnToDirection(Direction.WEST) - self.controller:EnableMiningForward() - self.controller:EnableMiningAbove() - self.controller:MoveForward(center_width_left) - self.controller:DisableMiningForward() - self.controller:DisableMiningAbove() - self.controller:TurnToDirection(Direction.NORTH) - - -- Excavate left slices - print("Excavate left slices") - for i = 1,self.config.slices_left do - -- Move to the next slice + if self.config.slices_left > 0 then + -- Move to left slices starting location + local center_width_left = self.config.center_slice_width - center_width_right + self.controller:StorePosition() self.controller:TurnToDirection(Direction.WEST) self.controller:EnableMiningForward() self.controller:EnableMiningAbove() - self.controller:MoveForward(self.config.slice_padding) + self.controller:MoveForward(center_width_left) self.controller:DisableMiningForward() self.controller:DisableMiningAbove() self.controller:TurnToDirection(Direction.NORTH) - self:Excavate_WxHxL() + -- Excavate left slices + print("Excavate left slices") + for i = 1,self.config.slices_left do + -- Move to the next slice + self.controller:TurnToDirection(Direction.WEST) + self.controller:EnableMiningForward() + self.controller:EnableMiningAbove() + self.controller:MoveForward(self.config.slice_padding) + self.controller:DisableMiningForward() + self.controller:DisableMiningAbove() + self.controller:TurnToDirection(Direction.NORTH) - if i == self.config.slices_left then - break + self:Excavate_WxHxL() + + if i == self.config.slices_left then + break + end + + self.controller:TurnToDirection(Direction.WEST) + self.controller:EnableMiningForward() + self.controller:EnableMiningAbove() + self.controller:MoveForward(self.config.slice_width) + self.controller:DisableMiningForward() + self.controller:DisableMiningAbove() + self.controller:TurnToDirection(Direction.NORTH) end - - self.controller:TurnToDirection(Direction.WEST) - self.controller:EnableMiningForward() - self.controller:EnableMiningAbove() - self.controller:MoveForward(self.config.slice_width) - self.controller:DisableMiningForward() - self.controller:DisableMiningAbove() - self.controller:TurnToDirection(Direction.NORTH) + self.controller:MoveBack() -- (0, 0, 1) end - self.controller:MoveBack() -- (0, 0, 1) -- Finish up self.controller:MoveToPosition(0, 0, 0, self.controller.config.storage_direction) self.controller:DropInventory() self.controller:TurnToDirection(Direction.NORTH) + self.audio:StopPlaying() end @@ -317,7 +325,7 @@ function ExcavationController:Run() turtle.refuel() self.controller:RefuelIfEmpty() - self:Excavate() + parallel.waitForAll(function() self:Excavate() end, self.audio:PlayAudioFactory("bangarang")) end diff --git a/main.lua b/main.lua index 15d6772..e3050ca 100644 --- a/main.lua +++ b/main.lua @@ -1,15 +1,18 @@ local TestingController = require("controller.testing_controller") local ExcavationController = require("controller.excavation_controller") +local AudioController = require("controller.audio_controller") local controllers = { TestingController:Create(), ExcavationController:Create(), + AudioController:Create(), } print("Multiple controllers are available:") print("1: Testing Mode") print("2: Volume Excavation") +print("3: Play Bangarang") local choice = 0 while choice < 1 or choice > #controllers do