Added terraformer, train scripts.
This commit is contained in:
parent
137b8ff572
commit
d2f5211cce
|
@ -0,0 +1,31 @@
|
||||||
|
--[[
|
||||||
|
Author: Andrew Lalis
|
||||||
|
File: ir_train_control.lua
|
||||||
|
Version: 1.0
|
||||||
|
Last Modified: 12-06-2018
|
||||||
|
|
||||||
|
Description:
|
||||||
|
Library which simplifies functions that are often used with immersive railroads
|
||||||
|
trains and their track augments.
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ir_train_control = {}
|
||||||
|
|
||||||
|
--Require statements and component definitions.
|
||||||
|
local component = require("component")
|
||||||
|
local detector = component.ir_augment_detector
|
||||||
|
local controller = component.ir_augment_control
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Pulls the ir_train_overhead event, and passes the results to a function defined
|
||||||
|
elsewhere.
|
||||||
|
func - function(net_address, augment_type, stock_uuid): Function to handle
|
||||||
|
pulled events.
|
||||||
|
--]]
|
||||||
|
local function ir_train_control.pullTrainEvent(func)
|
||||||
|
local event_name, net_address, augment_type, stock_uuid = event.pull("ir_train_overhead")
|
||||||
|
func(net_address, augment_type, stock_uuid)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function ir_train_control.
|
|
@ -0,0 +1,81 @@
|
||||||
|
--[[
|
||||||
|
Author: Andrew Lalis
|
||||||
|
File: train_speed_checkpoint.lua
|
||||||
|
Version: 1.0
|
||||||
|
Last Modified: 16-06-2018
|
||||||
|
|
||||||
|
Script used for helping to control the speed of a train. Use many
|
||||||
|
computers running this script to calibrate trains to run at a certain speed.
|
||||||
|
--]]
|
||||||
|
|
||||||
|
--Require statements and component definitions.
|
||||||
|
local component = require("component")
|
||||||
|
local event = require("event")
|
||||||
|
local computer = require("computer")
|
||||||
|
local term = require("term")
|
||||||
|
local detector = component.ir_augment_detector
|
||||||
|
local controller = component.ir_augment_control
|
||||||
|
|
||||||
|
-- Optimal Speed.
|
||||||
|
local DESIRED_SPEED = 20
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Shortcut for pulling only train events.
|
||||||
|
func - function(net_address, augment_type, stock_uuid): function to handle the
|
||||||
|
train event, with augment type being either DETECTOR or LOCO_CONTROL.
|
||||||
|
--]]
|
||||||
|
local function pullTrainEvent(func)
|
||||||
|
local event_name, net_address, augment_type, stock_uuid = event.pull("ir_train_overhead")
|
||||||
|
func(net_address, augment_type, stock_uuid)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Determines if a string starts with a given substring.
|
||||||
|
return - boolean: true if str starts with start, false otherwise.
|
||||||
|
--]]
|
||||||
|
local function strStarts(str, start)
|
||||||
|
return string.sub(str, 1, string.len(start)) == start
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Determines if a stock car over the detector is a locomotive by reading info.id
|
||||||
|
from the detector's info() method. If it begins with rolling_stock/loc, then
|
||||||
|
it is a locomotive.
|
||||||
|
--]]
|
||||||
|
local function isStockLocomotive(id)
|
||||||
|
return strStarts(id, "rolling_stock/loc")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function balanceSpeed(info, target_speed)
|
||||||
|
local diff = target_speed - info.speed
|
||||||
|
local percent_diff = info.speed / target_speed
|
||||||
|
if diff > 0 then -- We are too slow.
|
||||||
|
controller.setBrake(0)
|
||||||
|
controller.setThrottle(info.throttle + percent_diff)
|
||||||
|
else -- We are too fast.
|
||||||
|
controller.setThrottle(0)
|
||||||
|
controller.setBrake(percent_diff)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function handleTrainEvent(net_address, augment_type, stock_uuid)
|
||||||
|
local info = detector.info()
|
||||||
|
local data = detector.consist()
|
||||||
|
if not (data and info and isStockLocomotive(info.id)) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if (augment_type == "DETECTOR") then
|
||||||
|
term.clear()
|
||||||
|
term.setCursor(1, 1)
|
||||||
|
term.write(" Speed: "..data.speed_km.." Km/h")
|
||||||
|
term.write(" Dir: "..data.direction)
|
||||||
|
term.write(" Weight: "..data.weight_kg.." Kg")
|
||||||
|
end
|
||||||
|
if (augment_type == "LOCO_CONTROL") then
|
||||||
|
balanceSpeed(info, DESIRED_SPEED)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
while true do
|
||||||
|
pullTrainEvent(handleTrainEvent)
|
||||||
|
end
|
|
@ -0,0 +1,84 @@
|
||||||
|
--[[
|
||||||
|
Author: Andrew Lalis
|
||||||
|
File: train_speed_checkpoint.lua
|
||||||
|
Version: 1.0
|
||||||
|
Last Modified: 16-06-2018
|
||||||
|
|
||||||
|
Script used for helping to control the speed of a train. Use many
|
||||||
|
computers running this script to calibrate trains to run at a certain speed.
|
||||||
|
--]]
|
||||||
|
|
||||||
|
--Require statements and component definitions.
|
||||||
|
local component = require("component")
|
||||||
|
local event = require("event")
|
||||||
|
local computer = require("computer")
|
||||||
|
local detector = component.ir_augment_detector
|
||||||
|
local controller = component.ir_augment_control
|
||||||
|
|
||||||
|
local BRAKE_ENABLED = false
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Shortcut for pulling only train events.
|
||||||
|
func - function(net_address, augment_type, stock_uuid): function to handle the
|
||||||
|
train event, with augment type being either DETECTOR or LOCO_CONTROL.
|
||||||
|
--]]
|
||||||
|
local function pullTrainEvent(func)
|
||||||
|
local event_name, net_address, augment_type, stock_uuid = event.pull("ir_train_overhead")
|
||||||
|
func(net_address, augment_type, stock_uuid)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Determines if a string starts with a given substring.
|
||||||
|
return - boolean: true if str starts with start, false otherwise.
|
||||||
|
--]]
|
||||||
|
local function strStarts(str, start)
|
||||||
|
return string.sub(str, 1, string.len(start)) == start
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Determines if a stock car over the detector is a locomotive by reading info.id
|
||||||
|
from the detector's info() method. If it begins with rolling_stock/loc, then
|
||||||
|
it is a locomotive.
|
||||||
|
--]]
|
||||||
|
local function isStockLocomotive()
|
||||||
|
local info = detector.info()
|
||||||
|
return strStarts(info.id, "rolling_stock/loc")
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Main function to perform test. Currently configured to determine the distance
|
||||||
|
needed to stop a train. It does this by waiting for a train to go over the
|
||||||
|
detector, and then applies full brakes, idle throttle, and the train will slow
|
||||||
|
to a halt. It also records the current time at which the locomotive was
|
||||||
|
detected, and some other information that is of use.
|
||||||
|
net_address - string: the network address of the adapter for the augment.
|
||||||
|
augment_type - string: either DETECTOR or LOCO_CONTROL.
|
||||||
|
stock_uuid - string: the unique id of the stock detected.
|
||||||
|
--]]
|
||||||
|
local function handleTrainEvent(net_address, augment_type, stock_uuid)
|
||||||
|
if (augment_type == "DETECTOR") then
|
||||||
|
local data = detector.consist()
|
||||||
|
-- Only if there's data, and this is a locomotive, do we continue.
|
||||||
|
if (data == nil or not isStockLocomotive()) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
print("Locomotive Data from: "..net_address)
|
||||||
|
print(" Speed: "..data.speed_km.." Km/h")
|
||||||
|
print(" Direction: "..data.direction)
|
||||||
|
print(" Weight: "..data.weight_kg.." Kg")
|
||||||
|
print(" Tractive Effort: "..data.tractive_effort_N.." N")
|
||||||
|
print(" Cars: "..data.cars)
|
||||||
|
print(" TIME: "..os.time())
|
||||||
|
end
|
||||||
|
-- In the case that the train is over the control augment, apply changes to locomotive control.
|
||||||
|
-- Also sound horn.
|
||||||
|
if (augment_type == "LOCO_CONTROL" and BRAKE_ENABLED) then
|
||||||
|
controller.setThrottle(0)
|
||||||
|
controller.setBrake(1)
|
||||||
|
controller.horn()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
while true do
|
||||||
|
pullTrainEvent(handleTrainEvent)
|
||||||
|
end
|
|
@ -0,0 +1,212 @@
|
||||||
|
--[[
|
||||||
|
Author: Andrew Lalis
|
||||||
|
File: terraformer.lua
|
||||||
|
Version: 1.0
|
||||||
|
Last Modified: 16-06-2018
|
||||||
|
|
||||||
|
Description:
|
||||||
|
This script enables a robot to make drastic, albeit slow, changes to the
|
||||||
|
terrain of an area, through several sub-functions, such as flattening, filling,
|
||||||
|
and removal of trees.
|
||||||
|
--]]
|
||||||
|
|
||||||
|
--Require statements and componenent definitions.
|
||||||
|
local robot = require("robot")
|
||||||
|
local component = require("component")
|
||||||
|
local ic = component.inventory_controller
|
||||||
|
|
||||||
|
--Runtime Constants defined for this robot.
|
||||||
|
local SAPLING_NAME = "minecraft:sapling"
|
||||||
|
local SAPLING_DATA = 0
|
||||||
|
local BONEMEAL_NAME = "minecraft:dye"
|
||||||
|
local BONEMEAL_DATA = 15
|
||||||
|
|
||||||
|
--Global configuration variables.
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Exits the program.
|
||||||
|
--]]
|
||||||
|
local function quit()
|
||||||
|
print("#--------------------------------#")
|
||||||
|
print("# Program exited. #")
|
||||||
|
os.exit()
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Select an item, given its name and damage value.
|
||||||
|
item_name - string: The id string for an item.
|
||||||
|
item_data - number: The damage value, or variation of an item. Defaults to zero.
|
||||||
|
return - boolean: True if at least one slot contains the item. That slot is now
|
||||||
|
selected.
|
||||||
|
--]]
|
||||||
|
local function selectItemByName(item_name, item_data)
|
||||||
|
for i=1,16 do
|
||||||
|
local stack = ic.getStackInInternalSlot(i)
|
||||||
|
if (stack ~= nil and stack.name == item_name and stack.damage == item_data) then
|
||||||
|
robot.select(i)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Select an item, similar to selectItemByName, but if the item cannot be found,
|
||||||
|
the user will be prompted to add it to the robot's inventory and press enter to
|
||||||
|
continue.
|
||||||
|
item_name - string: The id string for an item.
|
||||||
|
item_data - number: The damage value, or variation of an item. Defaults to zero.
|
||||||
|
return - nil: If set to be continuous, then if the item cannot be found, then
|
||||||
|
the program will exit. If not, it will loop until the item is provided by the
|
||||||
|
user.
|
||||||
|
--]]
|
||||||
|
local function selectSafely(item_name, item_data)
|
||||||
|
local success = selectItemByName(item_name, item_data)
|
||||||
|
while not success do
|
||||||
|
print("Cannot find "..item_name.." in inventory. Please add some, and press enter.")
|
||||||
|
io.read()
|
||||||
|
success = selectItemByName(item_name, item_data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function repeatUntilSuccess(robot_func)
|
||||||
|
local success = robot_func()
|
||||||
|
while not success do
|
||||||
|
success = robot_func()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Uses the robot's axe to chop a tree, and quits if the lumber axe provided has
|
||||||
|
less than 10% durability.
|
||||||
|
--]]
|
||||||
|
local function chopTree()
|
||||||
|
local durability = robot.durability()
|
||||||
|
if continuous and (durability == nil or durability < 0.1) then
|
||||||
|
print("Inadequate tool to chop trees, exiting.")
|
||||||
|
quit()
|
||||||
|
end
|
||||||
|
while (durability == nil) or (durability < 0.1) do
|
||||||
|
print("Please ensure that a lumber axe with at least 10% durability is equipped in the tool slot, and press enter.")
|
||||||
|
io.read()
|
||||||
|
durability = robot.durability()
|
||||||
|
end
|
||||||
|
robot.swing()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ensureToolDurability()
|
||||||
|
local n1, n2, n3 = robot.durability()
|
||||||
|
while (n1 == nil and n2 == "no tool equipped") or (n1 < 0.01) do
|
||||||
|
print("Please enter a valid tool with enough durability, and press enter.")
|
||||||
|
io.read()
|
||||||
|
n1, n2, n3 = robot.durability()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function safeSwing(func)
|
||||||
|
ensureToolDurability()
|
||||||
|
repeatUntilSuccess(func)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function flattenSpot()
|
||||||
|
-- First try to dig until it can't dig anymore.
|
||||||
|
local displacement = 0
|
||||||
|
while robot.detectUp() do
|
||||||
|
safeSwing(robot.swingUp)
|
||||||
|
repeatUntilSuccess(robot.up)
|
||||||
|
displacement = displacement + 1
|
||||||
|
end
|
||||||
|
for i=1, displacement do
|
||||||
|
repeatUntilSuccess(robot.down)
|
||||||
|
end
|
||||||
|
-- Then place any floor blocks if needed.
|
||||||
|
local success, data = robot.detectDown()
|
||||||
|
if not (success and data == "solid") then
|
||||||
|
-- Remove any grass or other obstructions below.
|
||||||
|
if success then
|
||||||
|
local obstructed = success
|
||||||
|
while obstructed do
|
||||||
|
safeSwing(robot.swingDown)
|
||||||
|
obstructed, data = robot.detectDown()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
selectSafely("minecraft:dirt", 0)
|
||||||
|
repeatUntilSuccess(robot.placeDown)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function flattenArea(length, width)
|
||||||
|
for row=1, length do
|
||||||
|
print("Beginning row "..row.." of "..length..".")
|
||||||
|
if (robot.detect()) then
|
||||||
|
safeSwing(robot.swing)
|
||||||
|
end
|
||||||
|
repeatUntilSuccess(robot.forward)
|
||||||
|
if (row%2) == 1 then
|
||||||
|
robot.turnRight()
|
||||||
|
else
|
||||||
|
robot.turnLeft()
|
||||||
|
end
|
||||||
|
for col=1, width-1 do
|
||||||
|
flattenSpot()
|
||||||
|
if robot.detect() then
|
||||||
|
safeSwing(robot.swing)
|
||||||
|
end
|
||||||
|
repeatUntilSuccess(robot.forward)
|
||||||
|
end
|
||||||
|
flattenSpot()
|
||||||
|
if (row%2) == 1 then
|
||||||
|
robot.turnLeft()
|
||||||
|
else
|
||||||
|
robot.turnRight()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getNumberInput(str, lower_bound, upper_bound)
|
||||||
|
print(str)
|
||||||
|
local choice = tonumber(io.read())
|
||||||
|
while (choice == nil or choice < lower_bound or choice > upper_bound) do
|
||||||
|
print("Invalid input! Enter a number n such that "..lower_bound.." <= n <= "..upper_bound)
|
||||||
|
choice = tonumber(io.read())
|
||||||
|
end
|
||||||
|
return choice
|
||||||
|
end
|
||||||
|
|
||||||
|
local function flattenMenu()
|
||||||
|
length = getNumberInput("Enter the length (distance forward).", 1, 256)
|
||||||
|
width = getNumberInput("Enter the width (distance to the right).", 1, 256)
|
||||||
|
print("Flattening a "..length.." x "..width.." area. Total of "..(length*width).." spots to flatten.")
|
||||||
|
flattenArea(length, width)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function treeRemovalMenu()
|
||||||
|
quit()-- Implement this!
|
||||||
|
end
|
||||||
|
|
||||||
|
local function mainMenu()
|
||||||
|
print("# Andrew's Terraformer #")
|
||||||
|
print("# Copyright 2018 Andrew Lalis #")
|
||||||
|
print("#--------------------------------#")
|
||||||
|
print("1. Flatten")
|
||||||
|
print("2. Remove Trees (Not yet implemented)")
|
||||||
|
print("Please enter a number corresponding to one of the options above, or -1 to quit.")
|
||||||
|
local choice = tonumber(io.read())
|
||||||
|
if choice == 1 then
|
||||||
|
flattenMenu()
|
||||||
|
elseif choice == 2 then
|
||||||
|
treeRemovalMenu()
|
||||||
|
else
|
||||||
|
quit()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Main function in which the iterations of the cycle are performed.
|
||||||
|
--]]
|
||||||
|
local function main()
|
||||||
|
mainMenu()
|
||||||
|
quit()
|
||||||
|
end
|
||||||
|
|
||||||
|
main()
|
Loading…
Reference in New Issue