Skip to content

Commit e4b1597

Browse files
committed
feat: 🚧 Peripherals
1 parent 93f9288 commit e4b1597

File tree

7 files changed

+308
-63
lines changed

7 files changed

+308
-63
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/config
22
/.vscode
3-
/computer
3+
/computer
4+
/suits

generalFunctions.lua

Lines changed: 0 additions & 16 deletions
This file was deleted.

inventory.lua

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@
3030
---@field select fun(self: inventory, slot: integer): boolean
3131
---@field list fun(): item[]
3232
---@field __index any
33-
34-
local deepCopy = require("../generalFunctions").deepCopy
33+
---@field deepCopy fun(table: table): table
3534

3635
---# inventory
3736
---Inventory system emulated
@@ -108,7 +107,7 @@ local function pickUpItem(inventory, item, slot)
108107
local toTransfer = math.min(space, item.count)
109108

110109
local currentCount = getItemCount(inventory, fittingSlot)
111-
inventory[fittingSlot] = deepCopy(item)
110+
inventory[fittingSlot] = inventory.deepCopy(item)
112111
if (inventory[fittingSlot] == nil) then
113112
inventory[fittingSlot].maxcount = item.maxcount or inventory.defaultMaxSlotSize
114113
end
@@ -138,12 +137,15 @@ end
138137

139138
--- ### Description:
140139
---creates an Instance of of the Inventory class
141-
---@param inventorySize any
142-
function inventory:createInventory(inventorySize)
140+
---@param inventorySize number | nil
141+
---@param deepCopy fun(table: table): table
142+
---@return inventory
143+
function inventory:createInventory(inventorySize, deepCopy)
143144
local i = {
144145
inventorySize = inventorySize or 27,
145146
selectedSlot = 1,
146147
defaultMaxSlotSize = 64,
148+
deepCopy = deepCopy
147149
}
148150
setmetatable(i, self)
149151
self.__index = self
@@ -224,7 +226,7 @@ function inventory:transferTo(slot, count)
224226
if currentSlot == nil then
225227
return true
226228
end
227-
self[slot] = deepCopy(self[self.selectedSlot])
229+
self[slot] = self.deepCopy(self[self.selectedSlot])
228230
self[slot].count = math.min(self[slot] and self[slot].maxcount or 0 , count)
229231
local transferTo = math.min(currentSlot.count, count)
230232
currentSlot.count = currentSlot.count - transferTo

peripheral.lua

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---@alias filterFunc fun(name: string, wrapped: table):boolean
2+
3+
---@alias relativePosition
4+
--- | "front"
5+
--- | "back"
6+
--- | "top"
7+
--- | "bottom"
8+
--- | "left"
9+
--- | "right"
10+
11+
---@class peripheral
12+
---@field turtle TurtleMock
13+
---@field linkToTurtle fun(peripheral: peripheral, turtle: TurtleMock):peripheral
14+
---@field find fun(peripheral: peripheral, typeName: string, filterFunc: filterFunc | nil):table | nil
15+
---@field getMethods fun(peripheral: peripheral, name: any):string[] | nil
16+
---@field getNames fun(peripheral: peripheral):string[]
17+
---@field isPresent fun(peripheral: peripheral, positionOrname: any):boolean
18+
---@field __index peripheral
19+
20+
---@param turtle TurtleMock
21+
---@return position[]
22+
local function getPositions(turtle)
23+
24+
return pos
25+
end
26+
27+
---@type peripheral
28+
---@diagnostic disable-next-line: missing-fields
29+
local peripheral = {}
30+
---create a new instance of a peripheral and link it to a turtle
31+
---@param turtle TurtleMock
32+
---@return peripheral
33+
function peripheral:linkToTurtle(turtle)
34+
local mt = {
35+
turtle = turtle,
36+
}
37+
local proxy = {}
38+
mt.__index = function (_, key)
39+
local value = peripheral[key]
40+
if type(value) == "function" then
41+
return function(...)
42+
local mightBeSelf = select(1, ...)
43+
if mightBeSelf == peripheral then
44+
return value(...)
45+
elseif mightBeSelf == proxy then
46+
---@diagnostic disable-next-line: missing-parameter
47+
return value(peripheral, select(2, ...))
48+
end
49+
return value(peripheral, ...)
50+
end
51+
end
52+
return value
53+
end
54+
mt.__newindex = function (_, key, value)
55+
peripheral[key] = value
56+
end
57+
58+
setmetatable(proxy, mt)
59+
return proxy
60+
61+
end
62+
63+
---@param self peripheral
64+
---@param typeName string
65+
---@param filterFunc filterFunc | nil
66+
---@return table
67+
function peripheral:find(typeName, filterFunc)
68+
assert(self.turtle, "Peripheral is not linked to a turtle")
69+
local positions = getPositions(self.turtle.position)
70+
local peripheral
71+
for _, position in pairs(positions) do
72+
local block = self.turtle.emulator:getBlock(position)
73+
if block and block.peripheralName and block.peripheralName == typeName then
74+
peripheral = self.turtle.emulator:playPeripheralProxy(block)
75+
if peripheral and ((not filterFunc) or filterFunc(block.item.name, peripheral)) then
76+
return peripheral
77+
end
78+
end
79+
end
80+
end
81+
82+
---returns all the functions of a peripheral with the given name
83+
---@param name any
84+
---@return string[] | nil
85+
function peripheral:getMethods(name)
86+
local p = self:find(name)
87+
if not p then return nil end
88+
local methods = {}
89+
for k, v in pairs(p) do
90+
if type(v) == "function" then
91+
table.insert(methods, k)
92+
end
93+
end
94+
return methods
95+
end
96+
97+
---@return string[]
98+
function peripheral:getNames()
99+
local names = {}
100+
local positions = getPositions(self.turtle.position)
101+
for _, position in pairs(positions) do
102+
local block = self.turtle.emulator:getBlock(position)
103+
if block and block.peripheralName then
104+
if block.peripheralActions then
105+
table.insert(names, block.item.name)
106+
end
107+
end
108+
end
109+
return names
110+
end
111+
112+
--- Checks if a peripheral is present at the given position or with a given name
113+
---@param positionOrname any
114+
---@return boolean
115+
function peripheral:isPresent(positionOrname)
116+
117+
end
118+
119+
return peripheral

tests/test_spec.lua

Lines changed: 92 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,34 @@
2929
---@field equal function
3030
assert = assert
3131

32-
-- functions provided by busted, only available in the global scope
33-
describe = describe
34-
it = it
35-
setup = setup
36-
before_each = before_each
32+
-- installs the other suits
33+
if not pcall(function () io.open("./suits/vector/vector.lua", "r"):close() end) then
34+
print("Downloading TestSuite-lib")
35+
local http = require("socket.http")
36+
local url = "https://raw.githubusercontent.com/mc-cc-scripts/TestSuite-lib/master/installSuit.lua" -- URL of the installer
37+
local body, statusCode = http.request(url)
38+
if statusCode == 200 then
39+
local loader
40+
if _VERSION == "Lua 5.1" then
41+
loader = loadstring
42+
else
43+
loader = load
44+
end
45+
local installScript = loader(body)().install()
46+
else
47+
error("Failed to download TestSuite-lib: " .. tostring(statusCode))
48+
end
49+
end
50+
51+
-- load the other suits
52+
local vector = require("./suits/vector/vector")
53+
local deepCopy = require("./suits/helperFunctions/helperFunctions").deepCopy
54+
55+
print(deepCopy({a = 1, b = 2, c = 3}))
3756

3857
local turtleEmulator = require("../turtleEmulator")
58+
turtleEmulator:init(vector, deepCopy)
59+
local peripheral = require("../peripheral")
3960
describe("Disabled Movement", function()
4061
local turtle
4162
setup(function()
@@ -742,29 +763,72 @@ describe("Place", function()
742763
assert.are.equal("minecraft:water", block.item.name)
743764
end)
744765
end)
745-
describe("Chest", function()
766+
describe("peripherals", function()
746767
local turtle
747-
describe("Create Chests", function ()
748-
it("Create Chests", function ()
749-
turtleEmulator:clearBlocks()
750-
turtleEmulator:clearTurtles()
751-
turtleEmulator:createBlock({ item = {name = "minecraft:chest"}, position = { x = 1, y = 0, z = 0 } })
752-
local block = turtleEmulator:getBlock({ x = 1, y = 0, z = 0 })
753-
turtleEmulator:addInventoryToBlock(block.position)
754-
block.inventory:addItemToInventory({ name = "minecraft:stone", count = 64, maxcount = 64 })
755-
756-
block.inventory:select(2)
757-
758-
turtleEmulator:createBlock({ item = {name = "minecraft:chest"}, position = { x = 2, y = 0, z = 0 } })
759-
local block2 = turtleEmulator:getBlock({ x = 2, y = 0, z = 0 })
760-
turtleEmulator:addInventoryToBlock(block2.position)
761-
block2.inventory:select(2)
762-
assert.is_true(block2.inventory:addItemToInventory({ name = "minecraft:stone", count = 64, maxcount = 64 }, 2))
763-
assert.are.equal(64, block.inventory:getItemCount(1))
764-
assert.are.equal(0, block.inventory:getItemCount(2))
765-
assert.are.equal(0, block2.inventory:getItemCount(1))
766-
assert.are.equal(64, block2.inventory:getItemCount()) -- slot 2
767-
assert.are.equal(64, block2.inventory:getItemCount(2))
768-
end)
768+
before_each(function()
769+
turtleEmulator:clearBlocks()
770+
turtleEmulator:clearTurtles()
771+
turtle = turtleEmulator:createTurtle()
772+
end)
773+
it("Create Chests", function ()
774+
turtleEmulator:clearBlocks()
775+
turtleEmulator:clearTurtles()
776+
local block = turtleEmulator:createBlock({ item = {name = "minecraft:chest"}, position = { x = 1, y = 0, z = 0 } })
777+
local chest = turtleEmulator:addInventoryToBlock(block.position)
778+
chest:addItemToInventory({ name = "minecraft:stone", count = 64, maxcount = 64 })
779+
780+
chest:select(2)
781+
782+
local block2 = turtleEmulator:createBlock({ item = {name = "minecraft:chest"}, position = { x = 2, y = 0, z = 0 } })
783+
local chest2 = turtleEmulator:addInventoryToBlock({ x = 2, y = 0, z = 0 })
784+
chest2:select(2)
785+
assert.is_true(chest2:addItemToInventory({ name = "minecraft:stone", count = 64, maxcount = 64 }, 2))
786+
assert.are.equal(64, chest:getItemCount(1))
787+
assert.are.equal(0, chest:getItemCount(2))
788+
assert.are.equal(0, chest2.getItemCount(1))
789+
assert.are.equal(64, chest2.getItemCount()) -- slot 2
790+
assert.are.equal(64, chest2.getItemCount(2))
791+
-- check the ORIGINAL block in the emulator
792+
-- since the return is just a proxy
793+
assert.are.equal(64, block2.peripheralActions[2].count)
794+
end)
795+
it("isPresent", function()
796+
turtle.position = { x = 5, y = 0, z = 5 }
797+
local p = peripheral.linkToTurtle(turtle)
798+
799+
local block = turtleEmulator:createBlock({ item = {name = "minecraft:chest"}, position = { x = 5, y = 0, z = 6 } })
800+
turtleEmulator:addInventoryToBlock(block.position)
801+
assert.is_true(p.isPresent("right"))
802+
assert.is_false(p.isPresent("front"))
803+
assert.is_false(p.isPresent("left"))
804+
assert.is_false(p.isPresent("back"))
805+
assert.is_false(p.isPresent("up"))
806+
assert.is_false(p.isPresent("down"))
807+
local block2 = turtleEmulator:createBlock({ item = {name = "minecraft:chest"}, position = { x = 6, y = 0, z = 5 } })
808+
turtleEmulator:addInventoryToBlock(block2.position)
809+
assert.is_true(p.isPresent("front"))
810+
assert.is_true(p.isPresent("right"))
811+
assert.is_false(p.isPresent("left"))
812+
assert.is_false(p.isPresent("back"))
813+
turtle.turnRight()
814+
assert.is_true(p.isPresent("right"))
815+
assert.is_true(p.isPresent("back"))
816+
assert.is_false(p.isPresent("left"))
817+
assert.is_false(p.isPresent("front"))
818+
turtle.turnRight()
819+
assert.is_true(p.isPresent("back"))
820+
assert.is_true(p.isPresent("left"))
821+
assert.is_false(p.isPresent("front"))
822+
assert.is_false(p.isPresent("right"))
823+
turtle.turnRight()
824+
assert.is_true(p.isPresent("left"))
825+
assert.is_true(p.isPresent("front"))
826+
assert.is_false(p.isPresent("right"))
827+
assert.is_false(p.isPresent("back"))
828+
turtle.turnRight()
829+
assert.is_true(p.isPresent("front"))
830+
assert.is_true(p.isPresent("right"))
831+
assert.is_false(p.isPresent("left"))
832+
assert.is_false(p.isPresent("back"))
769833
end)
770834
end)

0 commit comments

Comments
 (0)