Fix a couple of back-compatibility issues

- Add back red{set,probe,pulse}. Remove usage of analogue functions, as
   these don't exist on older versions (and is gonna be really hard to
   patch back in).

 - Remove turtle equip methods, as these are redundant.

 - Add turtle.{getSelectedSlot, getFuelLimit}. The latter is kinda
   useless (fuel limits come later!), but useful for compatibility.
This commit is contained in:
Jonathan Coates 2023-06-13 20:04:13 +01:00
parent 0bb6ec39bd
commit 5426d880f0
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
10 changed files with 215 additions and 122 deletions

View File

@ -38,6 +38,11 @@ public class ClassTransformer implements IClassTransformer {
"dan200.computer.shared.TileEntityMonitor",
"cc.tweaked.patch.mixins.TileEntityMonitorMixin"
))
// And extend the turtle API
.atClass("dan200.turtle.shared.TurtleAPI", new ClassMerger(
"dan200.turtle.shared.TurtleAPI",
"cc.tweaked.patch.mixins.TurtleAPIMixin"
))
// Load from our ROM instead of the CC one. We do this by:
// 1. Changing the path of the assets folder.
.atMethod(

View File

@ -0,0 +1,45 @@
// Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
//
// SPDX-License-Identifier: LicenseRef-CCPL
package cc.tweaked.patch.mixins;
import cc.tweaked.patch.framework.transform.MergeVisitor;
import dan200.CCTurtle;
import dan200.computer.core.ILuaAPI;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.turtle.shared.ITurtle;
/**
* Adds additional methods to {@link dan200.turtle.shared.TurtleAPI}.
*/
public abstract class TurtleAPIMixin implements ILuaAPI {
@MergeVisitor.Shadow
private ITurtle m_turtle;
/**
* Get the currently selected slot.
*
* @return The current slot.
* @cc.since 1.6
*/
@LuaFunction
public final int getSelectedSlot() {
return m_turtle.getSelectedSlot() + 1;
}
/**
* Get the maximum amount of fuel this turtle can hold.
* <p>
* By default, normal turtles have a limit of 20,000 and advanced turtles of 100,000.
*
* @return The limit, or "unlimited".
* @cc.treturn [1] number The maximum amount of fuel a turtle can hold.
* @cc.treturn [2] "unlimited" If turtles do not consume fuel when moving.
* @cc.since 1.6
*/
@LuaFunction
public final Object getFuelLimit() {
return CCTurtle.turtlesNeedFuel ? Integer.MAX_VALUE : "unlimited";
}
}

View File

@ -100,7 +100,7 @@ local expect = dofile("rom/modules/main/cc/expect.lua").expect
local native = peripheral
-- Stub in peripheral.hasType
function native.hasType(p, type) return peripheral.getType(p) == type end
function native.hasType(p, ty) return native.getType(p) == ty end
local sides = rs.getSides()

View File

@ -14,31 +14,53 @@ end
-- should not need to use it.
native = turtle.native or turtle
local function addCraftMethod(object)
if peripheral.getType("left") == "workbench" then
object.craft = function(...)
return peripheral.call("left", "craft", ...)
local function waitForResponse(_id)
local event, responseID, success
while event ~= "turtle_response" or responseID ~= _id do
event, responseID, success = os.pullEvent("turtle_response")
end
return success
end
local function wrap(_sCommand)
return function(...)
local id = native[_sCommand](...)
if id == -1 then
return false
end
elseif peripheral.getType("right") == "workbench" then
object.craft = function(...)
return peripheral.call("right", "craft", ...)
return waitForResponse(id)
end
end
-- Wrap standard commands
local turtle = {}
turtle["getItemCount"] = native.getItemCount
turtle["getItemSpace"] = native.getItemSpace
turtle["getFuelLevel"] = native.getFuelLevel
turtle["getSelectedSlot"] = native.getSelectedSlot
turtle["getFuelLimit"] = native.getFuelLimit
for k,v in pairs(native) do
if type(k) == "string" and type(v) == "function" then
if turtle[k] == nil then
turtle[k] = wrap(k)
end
else
object.craft = nil
end
end
-- Wrap peripheral commands
if peripheral.getType("left") == "workbench" then
turtle["craft"] = function(...)
local id = peripheral.call("left", "craft", ...)
return waitForResponse(id)
end
elseif peripheral.getType("right") == "workbench" then
turtle["craft"] = function(...)
local id = peripheral.call("right", "craft", ...)
return waitForResponse(id)
end
end
-- Put commands into environment table
local env = _ENV
for k, v in pairs(native) do
if k == "equipLeft" or k == "equipRight" then
env[k] = function(...)
local result, err = v(...)
addCraftMethod(turtle)
return result, err
end
else
env[k] = v
end
end
addCraftMethod(env)
for k,v in pairs(turtle) do env[k] = v end

View File

@ -0,0 +1,57 @@
-- Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
--
-- SPDX-License-Identifier: LicenseRef-CCPL
-- Regular input
print("Redstone inputs: ")
local count = 0
local bundledCount = 0
for n,sSide in ipairs(redstone.getSides()) do
if redstone.getBundledInput(sSide) > 0 then
bundledCount = bundledCount + 1
end
if redstone.getInput(sSide) then
if count > 0 then
io.write(", ")
end
io.write(sSide)
count = count + 1
end
end
if count > 0 then
print(".")
else
print("None.")
end
-- Bundled input
if bundledCount > 0 then
print()
print("Bundled inputs:")
for i,sSide in ipairs(redstone.getSides()) do
if redstone.getBundledInput(sSide) > 0 then
write(sSide.." = "..redstone.getBundledInput(sSide).." (")
local count = 0
for sColour,nColour in pairs(colors) do
if type(nColour) == "number" and
redstone.testBundledInput(sSide, nColour) then
if count > 0 then
write(" + ")
end
if term.isColour() then
term.setTextColour(nColour)
end
write(sColour)
if term.isColour() then
term.setTextColour(colours.white)
end
count = count + 1
end
end
print(")")
end
end
end

View File

@ -0,0 +1,20 @@
-- Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
--
-- SPDX-License-Identifier: LicenseRef-CCPL
local tArgs = { ... }
local sSide = tArgs[1]
if not sSide then
print("Usage: redpulse <side> <count> <period>")
return
end
local nCount = tonumber(tArgs[2]) or 1
local nPeriod = tonumber(tArgs[3]) or 0.5
for n=1,nCount do
redstone.setOutput(sSide, true)
sleep(nPeriod / 2)
redstone.setOutput(sSide, false)
sleep(nPeriod / 2)
end

View File

@ -0,0 +1,43 @@
-- Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
--
-- SPDX-License-Identifier: LicenseRef-CCPL
local tArgs = { ... }
if #tArgs == 0 or #tArgs > 3 then
print("Usages:")
print("redset <side> <true/false>")
print("redset <side> <number>")
print("redset <side> <color> <true/false>")
return
end
local sSide = tArgs[1]
if #tArgs == 2 then
local value = tArgs[2]
if tonumber(value) ~= nil then
redstone.setBundledOutput(sSide, tonumber(value))
elseif value == "true" or value == "false" then
redstone.setOutput(sSide, value == "true")
else
print("Value must be a number or true/false")
return
end
else
local sColour = tArgs[2]
local nColour = colors[sColour] or colours[sColour]
if type(nColour) ~= "number" then
print("No such color")
return
end
local sValue = tArgs[3]
if sValue == "true" then
rs.setBundledOutput(sSide, colors.combine(rs.getBundledOutput(sSide), nColour))
elseif sValue == "false" then
rs.setBundledOutput(sSide, colors.subtract(rs.getBundledOutput(sSide), nColour))
else
print("Value must be true/false")
return
end
end

View File

@ -103,15 +103,12 @@ elseif sCommand == "set" then
else
-- Regular output
local sValue = tArgs[3]
local nValue = tonumber(sValue)
if sValue == "true" then
rs.setOutput(sSide, true)
elseif sValue == "false" then
rs.setOutput(sSide, false)
elseif nValue and nValue >= 0 and nValue <= 15 then
rs.setAnalogOutput(sSide, nValue)
else
print("Value must be boolean or 0-15")
print("Value must be boolean")
end
end

View File

@ -1,47 +0,0 @@
-- SPDX-FileCopyrightText: 2017 Daniel Ratcliffe
--
-- SPDX-License-Identifier: LicenseRef-CCPL
if not turtle then
printError("Requires a Turtle")
return
end
local tArgs = { ... }
local function printUsage()
local programName = arg[0] or fs.getName(shell.getRunningProgram())
print("Usage: " .. programName .. " <slot> <side>")
end
if #tArgs ~= 2 then
printUsage()
return
end
local function equip(nSlot, fnEquipFunction)
turtle.select(nSlot)
local nOldCount = turtle.getItemCount(nSlot)
if nOldCount == 0 then
print("Nothing to equip")
elseif fnEquipFunction() then
local nNewCount = turtle.getItemCount(nSlot)
if nNewCount > 0 then
print("Items swapped")
else
print("Item equipped")
end
else
print("Item not equippable")
end
end
local nSlot = tonumber(tArgs[1])
local sSide = tArgs[2]
if sSide == "left" then
equip(nSlot, turtle.equipLeft)
elseif sSide == "right" then
equip(nSlot, turtle.equipRight)
else
printUsage()
return
end

View File

@ -1,49 +0,0 @@
-- SPDX-FileCopyrightText: 2017 Daniel Ratcliffe
--
-- SPDX-License-Identifier: LicenseRef-CCPL
if not turtle then
printError("Requires a Turtle")
return
end
local tArgs = { ... }
local function printUsage()
local programName = arg[0] or fs.getName(shell.getRunningProgram())
print("Usage: " .. programName .. " <side>")
end
if #tArgs ~= 1 then
printUsage()
return
end
local function unequip(fnEquipFunction)
for nSlot = 1, 16 do
local nOldCount = turtle.getItemCount(nSlot)
if nOldCount == 0 then
turtle.select(nSlot)
if fnEquipFunction() then
local nNewCount = turtle.getItemCount(nSlot)
if nNewCount > 0 then
print("Item unequipped")
return
else
print("Nothing to unequip")
return
end
end
end
end
print("No space to unequip item")
end
local sSide = tArgs[1]
if sSide == "left" then
unequip(turtle.equipLeft)
elseif sSide == "right" then
unequip(turtle.equipRight)
else
printUsage()
return
end