Updated LUA scripts for CC and OC
- changed general color and controls styles - fixed keyboard responsiveness - added weapon controller's enum handler to common library - added accelerator controller - added autorefresh - fixed common library duplication - fixed confirmation input so 'enter' means 'yes' - implemented LUA API changes - improved inputs handling in weapon controller - removed eXit command in favor of terminate shortcut (Ctrl-T / Ctrl-C) - splitted ship controls into 3 different sections - added more explicit help on home page, input controls, confirmation popup, etc. - added workaround for CC internal Java crash while connected to an Enantiomorphic reactor
This commit is contained in:
parent
78e2d187e2
commit
99221df636
17 changed files with 6401 additions and 5647 deletions
build.gradle
src/main/resources/assets/warpdrive
lua.ComputerCraft
common
warpdriveAccelerator
warpdriveEnanReactorCore
warpdriveMainframe
warpdriveShipController
warpdriveWeaponController
lua.OpenComputers
common
warpdriveAccelerator
warpdriveEnanReactorCore
warpdriveShipController
warpdriveWeaponController
29
build.gradle
29
build.gradle
|
@ -49,7 +49,7 @@ dependencies {
|
|||
// or you may define them like so..
|
||||
//compile "some.group:artifact:version:classifier"
|
||||
//compile "some.group:artifact:version"
|
||||
|
||||
|
||||
// real examples
|
||||
//compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
|
||||
//compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env
|
||||
|
@ -60,8 +60,7 @@ dependencies {
|
|||
|
||||
}
|
||||
|
||||
processResources
|
||||
{
|
||||
processResources {
|
||||
// this will ensure that this task is redone when the versions change.
|
||||
inputs.property "version", project.version
|
||||
inputs.property "mcversion", project.minecraft.version
|
||||
|
@ -69,7 +68,7 @@ processResources
|
|||
// skip source assets
|
||||
exclude '**/*.pdn'
|
||||
exclude '**/*.psd'
|
||||
|
||||
|
||||
// replace stuff in mcmod.info, nothing else
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
include 'mcmod.info'
|
||||
|
@ -77,14 +76,34 @@ processResources
|
|||
// replace version and mcversion
|
||||
expand 'version':project.version, 'mcversion':project.minecraft.version
|
||||
}
|
||||
|
||||
|
||||
// copy everything else, thats not the mcmod.info
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude 'mcmod.info'
|
||||
}
|
||||
}
|
||||
|
||||
//copies the commons folder to all instances
|
||||
task copyOpenComputersCommons1(type: Copy) {
|
||||
from 'src/main/resources/assets/warpdrive/lua.OpenComputers/common'
|
||||
into('build/resources/main/assets/warpdrive/lua.OpenComputers/warpdriveShipController')
|
||||
}
|
||||
task copyOpenComputersCommons2(type: Copy) {
|
||||
from 'src/main/resources/assets/warpdrive/lua.OpenComputers/common'
|
||||
into('build/resources/main/assets/warpdrive/lua.OpenComputers/warpdriveEnanReactorCore')
|
||||
}
|
||||
task copyOpenComputersCommons3(type: Copy) {
|
||||
from 'src/main/resources/assets/warpdrive/lua.OpenComputers/common'
|
||||
into('build/resources/main/assets/warpdrive/lua.OpenComputers/warpdriveWeaponController')
|
||||
}
|
||||
task copyOpenComputersCommons4(type: Copy) {
|
||||
from 'src/main/resources/assets/warpdrive/lua.OpenComputers/common'
|
||||
into('build/resources/main/assets/warpdrive/lua.OpenComputers/warpdriveAcceleratorController')
|
||||
}
|
||||
|
||||
jar {
|
||||
dependsOn copyOpenComputersCommons1, copyOpenComputersCommons2, copyOpenComputersCommons3, copyOpenComputersCommons4
|
||||
|
||||
manifest {
|
||||
attributes 'FMLAT': 'CoFH_at.cfg'
|
||||
attributes 'FMLCorePlugin': 'cr0s.warpdrive.core.FMLLoadingPlugin',
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,406 @@
|
|||
|
||||
if warpdriveCommons then os.unloadAPI("warpdriveCommons") end
|
||||
if not os.loadAPI("warpdrive/warpdriveCommons") then error("missing warpdriveCommons") end
|
||||
local w = warpdriveCommons.w
|
||||
|
||||
----------- Accelerator support
|
||||
|
||||
local lhc_isEnabled = false
|
||||
local lhc_controlPoints = {}
|
||||
local lhc_parameters = {}
|
||||
local accelerator = nil
|
||||
|
||||
function lhc_boot(isDetailed)
|
||||
if accelerator == nil then
|
||||
return
|
||||
end
|
||||
|
||||
if isDetailed == nil then
|
||||
isDetailed = true
|
||||
end
|
||||
|
||||
if isDetailed then
|
||||
w.write("Booting Accelerator controller")
|
||||
|
||||
w.writeLn("...")
|
||||
w.sleep(0.1)
|
||||
end
|
||||
|
||||
-- getting control points
|
||||
lhc_controlPoints = {}
|
||||
local count = accelerator.getControlPointsCount()
|
||||
lhc_controlChannels = { }
|
||||
countParameters = 0
|
||||
|
||||
if count ~= nil and count > 0 then
|
||||
for i = 0, count - 1 do
|
||||
local success, x, y, z, tier, type, isEnabled, controlChannel = accelerator.getControlPoint(i)
|
||||
if success then
|
||||
if isDetailed then
|
||||
w.write(type .. " " .. tier .. " #" .. controlChannel .. " @ (" .. w.format_integer(x, 6) .. " " .. w.format_integer(y, 3) .. " " .. w.format_integer(z, 6) .. ") ")
|
||||
if isEnabled then
|
||||
w.writeLn("Enabled")
|
||||
else
|
||||
w.writeLn("Disabled")
|
||||
end
|
||||
end
|
||||
lhc_controlPoints[i + 1] = { x, y, z, tier, type, isEnabled, controlChannel }
|
||||
lhc_controlChannels[controlChannel] = "true"
|
||||
countParameters = countParameters + 1
|
||||
elseif isDetailed then
|
||||
w.setColorWarning();
|
||||
w.writeLn("Error " .. x)
|
||||
w.setColorNormal();
|
||||
w.sleep(0.5)
|
||||
end
|
||||
end
|
||||
elseif isDetailed then
|
||||
w.setColorWarning();
|
||||
w.writeLn("No control point detected!")
|
||||
w.sleep(0.5)
|
||||
end
|
||||
|
||||
-- getting parameters
|
||||
local controlChannels = { accelerator.getParametersControlChannels() }
|
||||
if controlChannels ~= nil and #controlChannels > 0 then
|
||||
for key, value in pairs(controlChannels) do lhc_controlChannels[value] = { } end
|
||||
countParameters = countParameters + 1
|
||||
end
|
||||
lhc_parameters = {}
|
||||
if isDetailed then w.sleep(0.1) end
|
||||
|
||||
if countParameters ~= 0 then
|
||||
local index = 1
|
||||
for controlChannel, _ in pairs(lhc_controlChannels) do
|
||||
local success, controlChannelCheck, isEnabled, threshold, description = accelerator.parameter(controlChannel)
|
||||
if success ~= nil and success then
|
||||
if isDetailed then
|
||||
w.write("#" .. w.format_integer(controlChannelCheck, 9) .. " ")
|
||||
if isEnabled then
|
||||
w.write("Enabled")
|
||||
else
|
||||
w.write("Disabled")
|
||||
end
|
||||
w.writeLn(" " .. w.format_integer(threshold * 100, 3) .. "% '" .. description .. "'")
|
||||
end
|
||||
lhc_parameters[index] = { controlChannel, isEnabled, threshold, description }
|
||||
index = index + 1
|
||||
elseif isDetailed then
|
||||
w.setColorWarning();
|
||||
if controlChannelCheck ~= nil then
|
||||
w.writeLn("Error " .. controlChannelCheck)
|
||||
else
|
||||
w.writeLn("Error nil?")
|
||||
end
|
||||
w.sleep(0.5)
|
||||
w.setColorNormal();
|
||||
end
|
||||
if controlChannel ~= controlChannelCheck and isDetailed then
|
||||
w.setColorWarning();
|
||||
w.writeLn("Error: requested " .. controlChannel .. ", received " .. controlChannelCheck)
|
||||
w.sleep(0.5)
|
||||
w.setColorNormal();
|
||||
end
|
||||
end
|
||||
elseif isDetailed then
|
||||
w.setColorWarning();
|
||||
w.writeLn("No control channel detected!")
|
||||
w.sleep(0.5)
|
||||
end
|
||||
end
|
||||
|
||||
function lhc_page_parameter()
|
||||
w.page_begin("<==== Change accelerator parameter ====>")
|
||||
local _, indexSelected = lhc_parameter_getIndexes()
|
||||
local controlChannel, isEnabled, threshold, description = lhc_parameter_get(indexSelected)
|
||||
w.writeLn("Control channel #" .. w.format_integer(controlChannel, 9) .. " applies to:")
|
||||
for key, controlPoint in ipairs(lhc_controlPoints) do
|
||||
local cp_x, cp_y, cp_z, cp_tier, cp_type, cp_isEnabled, cp_controlChannel = unpack(controlPoint)
|
||||
if cp_controlChannel == controlChannel then
|
||||
w.write(string.format("%s %s @%s %s %s ",
|
||||
w.format_string(cp_type, 10),
|
||||
w.format_string(cp_tier, 1),
|
||||
w.format_integer(cp_x, 7), w.format_integer(cp_y, 3), w.format_integer(cp_z, 7) ))
|
||||
if isEnabled then
|
||||
w.writeLn("Enabled")
|
||||
else
|
||||
w.writeLn("Disabled")
|
||||
end
|
||||
end
|
||||
end
|
||||
w.writeLn("")
|
||||
w.writeLn("Current description is '" .. description .. "'")
|
||||
w.write("Enter a description: ")
|
||||
description = w.input_readText(description)
|
||||
|
||||
w.writeLn("")
|
||||
w.writeLn("Current theshold is " .. (threshold * 100) .. "%")
|
||||
w.write("Enter parameter threshold: ")
|
||||
local new_threshold = w.input_readNumber(threshold * 100) / 100
|
||||
threshold = math.min(2.0, math.max(0.0, new_threshold))
|
||||
lhc_parameters[indexSelected] = { controlChannel, isEnabled, threshold, description }
|
||||
accelerator.parameter(controlChannel, isEnabled, threshold, description)
|
||||
end
|
||||
|
||||
lhc_parameter_indexSelected = 1
|
||||
lhc_parameter_indexFirstLine = 1
|
||||
lhc_parameter_lines = 7
|
||||
function lhc_parameter_getIndexes()
|
||||
if lhc_parameters ~= nil then
|
||||
if lhc_parameter_indexSelected > #lhc_parameters then
|
||||
lhc_parameter_indexSelected = 1
|
||||
elseif lhc_parameter_indexSelected < 1 then
|
||||
lhc_parameter_indexSelected = #lhc_parameters
|
||||
end
|
||||
if lhc_parameter_indexFirstLine > lhc_parameter_indexSelected then
|
||||
lhc_parameter_indexFirstLine = lhc_parameter_indexSelected
|
||||
elseif lhc_parameter_indexFirstLine + lhc_parameter_lines < lhc_parameter_indexSelected then
|
||||
lhc_parameter_indexFirstLine = lhc_parameter_indexSelected - lhc_parameter_lines
|
||||
end
|
||||
return lhc_parameter_indexFirstLine, lhc_parameter_indexSelected
|
||||
else
|
||||
return 1, 1
|
||||
end
|
||||
end
|
||||
|
||||
function lhc_parameter_get(index)
|
||||
local parameter = lhc_parameters[index]
|
||||
local controlChannel, isEnabled, threshold, description = -1, false, 0, "-"
|
||||
if parameter == nil or #parameter ~= 4 then
|
||||
lhc_boot(false)
|
||||
w.status_showWarning("Invalid parameter at index " .. index)
|
||||
else
|
||||
controlChannel, isEnabled, threshold, description = unpack(parameter)
|
||||
end
|
||||
return controlChannel, isEnabled, threshold, description
|
||||
end
|
||||
|
||||
function lhc_parameter_updateThreshold(offset)
|
||||
if lhc_parameters ~= nil and offset ~= nil then
|
||||
local _, indexSelected = lhc_parameter_getIndexes()
|
||||
local controlChannel, isEnabled, threshold, description = lhc_parameter_get(indexSelected)
|
||||
threshold = math.min(2.0, math.max(0.0, threshold + offset / 100))
|
||||
lhc_parameters[indexSelected] = { controlChannel, isEnabled, threshold, description }
|
||||
accelerator.parameter(controlChannel, isEnabled, threshold, description)
|
||||
end
|
||||
end
|
||||
|
||||
function lhc_parameter_toggleEnable(forced)
|
||||
if lhc_parameters ~= nil then
|
||||
local _, index = lhc_parameter_getIndexes()
|
||||
local controlChannel, isEnabled, threshold, description = lhc_parameter_get(index)
|
||||
if forced == nil then
|
||||
isEnabled = not isEnabled
|
||||
else
|
||||
isEnabled = forced
|
||||
end
|
||||
lhc_parameters[index] = { controlChannel, isEnabled, threshold, description }
|
||||
accelerator.parameter(controlChannel, isEnabled, threshold, description)
|
||||
end
|
||||
end
|
||||
|
||||
function lhc_page()
|
||||
w.page_begin(w.data_getName() .. " - Accelerator controller")
|
||||
if accelerator ~= nil then
|
||||
-- w.writeLn("")
|
||||
local status, isEnabled, isPowered, energy, temperatureCurrent_K, temperatureTarget_K = accelerator.state()
|
||||
if status == nil then
|
||||
lhc_boot(false)
|
||||
w.status_showWarning("Invalid accelerator status, rebooting...")
|
||||
status, isEnabled, isPowered, energy, temperatureCurrent_K, temperatureTarget_K = "-", false, false, 0, 0, 0
|
||||
end
|
||||
w.writeLn("Accelerator status: " .. status)
|
||||
|
||||
w.write(" Controller is ")
|
||||
if isEnabled then
|
||||
w.setColorGood();
|
||||
w.writeLn("Enabled")
|
||||
else
|
||||
w.setColorBad();
|
||||
w.writeLn("Disabled")
|
||||
end
|
||||
|
||||
local energy, energyMax = accelerator.energy()
|
||||
if energy == nil then energy = 0 end
|
||||
if energyMax == nil or energyMax == 0 then energyMax = 1 end
|
||||
w.setColorNormal();
|
||||
w.write(" Energy level is ")
|
||||
if isPowered then
|
||||
w.setColorGood();
|
||||
elseif isEnabled then
|
||||
w.setColorBad();
|
||||
else
|
||||
w.setColorDisabled();
|
||||
end
|
||||
w.writeLn(math.floor(energy / energyMax * 100) .. " % (" .. energy .. "EU)")
|
||||
-- w.writeLn("")
|
||||
|
||||
w.setColorNormal();
|
||||
w.write(" Magnets temperature is ")
|
||||
if temperatureCurrent_K <= temperatureTarget_K then
|
||||
w.setColorGood();
|
||||
elseif isEnabled then
|
||||
w.setColorBad();
|
||||
else
|
||||
w.setColorDisabled();
|
||||
end
|
||||
w.write(string.format("%fK", math.floor(temperatureCurrent_K * 10) / 10))
|
||||
w.setColorNormal();
|
||||
w.writeLn(". Target is " .. temperatureTarget_K .. "K")
|
||||
-- w.writeLn("")
|
||||
|
||||
w.write("Parameters: ")
|
||||
if #lhc_parameters == 0 then
|
||||
w.setColorDisabled();
|
||||
w.writeLn("")
|
||||
w.writeCentered(" -no valid node detected-")
|
||||
else
|
||||
local indexFirstLine, indexSelected = lhc_parameter_getIndexes()
|
||||
w.writeLn(indexSelected .. "/" .. #lhc_parameters)
|
||||
local indexCurrent = indexFirstLine
|
||||
local indexLastLine = math.min(indexFirstLine + lhc_parameter_lines, #lhc_parameters)
|
||||
for indexCurrent = indexFirstLine, indexLastLine do
|
||||
if indexCurrent == indexSelected then
|
||||
w.setColorSelected()
|
||||
w.clearLine()
|
||||
w.write(">")
|
||||
else
|
||||
w.write(" ")
|
||||
end
|
||||
local controlChannel, isEnabled, threshold, description = lhc_parameter_get(indexCurrent)
|
||||
if description == "-" then
|
||||
description = "#" .. w.format_integer(controlChannel)
|
||||
end
|
||||
w.write(string.format("%s is ",
|
||||
w.format_string(description, 25) ))
|
||||
if isEnabled then
|
||||
w.write("enabled ")
|
||||
else
|
||||
w.write("disabled")
|
||||
end
|
||||
w.writeLn(", set to " .. w.format_integer(threshold * 100, 3) .. "%")
|
||||
w.setColorNormal()
|
||||
end
|
||||
end
|
||||
else
|
||||
w.status_showWarning("No accelerator controller detected")
|
||||
end
|
||||
|
||||
w.setCursorPos(1, 15)
|
||||
w.setColorControl()
|
||||
w.writeFullLine(" Start accelerator (S), Stop accelerator (P)")
|
||||
w.writeFullLine(" Select parameter (Up, Down), Enable parameter (E)")
|
||||
w.writeFullLine(" Change parameter (Enter), Adjust threshold (+, -)")
|
||||
end
|
||||
|
||||
function lhc_key(character, keycode)
|
||||
if character == 's' or character == 'S' then
|
||||
if accelerator ~= nil then
|
||||
accelerator.enable(true)
|
||||
else
|
||||
w.status_showWarning("No accelerator detected")
|
||||
end
|
||||
return true
|
||||
elseif character == 'p' or character == 'P' then
|
||||
if accelerator ~= nil then
|
||||
accelerator.enable(false)
|
||||
else
|
||||
w.status_showWarning("No accelerator detected")
|
||||
end
|
||||
return true
|
||||
elseif keycode == 200 or keycode == 203 then -- Up or Left arrow
|
||||
lhc_parameter_indexSelected = lhc_parameter_indexSelected - 1
|
||||
return true
|
||||
elseif keycode == 208 or keycode == 205 then -- Down or Right arrow
|
||||
lhc_parameter_indexSelected = lhc_parameter_indexSelected + 1
|
||||
return true
|
||||
elseif keycode == 28 or character == 'c' or character == 'C' then -- Return or Enter
|
||||
lhc_page_parameter()
|
||||
return true
|
||||
elseif character == '-' then
|
||||
lhc_parameter_updateThreshold(-1)
|
||||
return true
|
||||
elseif character == '+' then
|
||||
lhc_parameter_updateThreshold(1)
|
||||
return true
|
||||
elseif character == 'e' or character == 'E' or character == ' ' then
|
||||
lhc_parameter_toggleEnable()
|
||||
lhc_parameter_indexSelected = lhc_parameter_indexSelected + 1
|
||||
return true
|
||||
elseif character == 'y' or character == 'Y' then
|
||||
lhc_parameter_toggleEnable(true)
|
||||
lhc_parameter_indexSelected = lhc_parameter_indexSelected + 1
|
||||
return true
|
||||
elseif character == 'n' or character == 'N' then
|
||||
lhc_parameter_toggleEnable(false)
|
||||
lhc_parameter_indexSelected = lhc_parameter_indexSelected + 1
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function lhc_register()
|
||||
w.device_register("warpdriveAccelerator",
|
||||
function(deviceType, address, wrap) accelerator = wrap end,
|
||||
function() end)
|
||||
w.event_register("particleBunchCollided" , function() w.status_showSuccess("Particle bunch have collided") return false end )
|
||||
w.event_register("particleBunchInjected" , function() w.status_showSuccess("Particle bunch injection done") return false end )
|
||||
w.event_register("acceleratorCoolingReset", function() w.status_showWarning("Accelerator coolant has leaked! restarting...") return true end )
|
||||
w.event_register("acceleratorCoolingDone" , function() w.status_showSuccess("Accelerator cooling completed") return true end )
|
||||
w.event_register("acceleratorUpdated" , function() w.status_showSuccess("Accelerator updated") lhc_boot(false) return true end )
|
||||
end
|
||||
|
||||
----------- connections status
|
||||
|
||||
function connections_page(isBooting)
|
||||
w.page_begin(w.data_getName() .. " - Connections")
|
||||
|
||||
w.writeLn("")
|
||||
|
||||
local monitors = w.device_getMonitors()
|
||||
if #monitors == 0 then
|
||||
w.setColorDisabled()
|
||||
w.writeLn("No Monitor detected")
|
||||
elseif #monitors == 1 then
|
||||
w.setColorSuccess()
|
||||
w.writeLn("1 monitor detected")
|
||||
else
|
||||
w.setColorSuccess()
|
||||
w.writeLn(#monitors .. " Monitors detected")
|
||||
end
|
||||
|
||||
if accelerator == nil then
|
||||
w.setColorDisabled()
|
||||
w.writeLn("No accelerator controller detected")
|
||||
else
|
||||
w.setColorSuccess()
|
||||
w.writeLn("Accelerator controller detected")
|
||||
lhc_boot(isBooting)
|
||||
end
|
||||
|
||||
w.writeLn("")
|
||||
w.setColorNormal()
|
||||
w.writeLn("This is a keyboard controlled user interface.")
|
||||
w.write("Key controls are written like so: ")
|
||||
w.setColorControl()
|
||||
w.write("Action (key)")
|
||||
w.setColorNormal()
|
||||
w.writeLn(".")
|
||||
w.write("For example, typing ")
|
||||
w.setColorControl()
|
||||
w.write(" 1 ")
|
||||
w.setColorNormal()
|
||||
w.writeLn(" will open Accelerator")
|
||||
w.writeLn("controls.")
|
||||
end
|
||||
|
||||
----------- Boot sequence
|
||||
|
||||
w.page_setEndText(" Home (0), Accelerator controls (1)")
|
||||
w.page_register('0', connections_page, nil)
|
||||
w.page_register('1', lhc_page, lhc_key)
|
||||
lhc_register()
|
||||
|
||||
w.boot()
|
||||
w.run()
|
||||
w.close()
|
File diff suppressed because it is too large
Load diff
|
@ -1070,7 +1070,7 @@ function core_page()
|
|||
WriteLn(" x, y, z = " .. X .. ", " .. Y .. ", " .. Z)
|
||||
local energy, energyMax = ship.energy()
|
||||
if energy == nil then energy = 0 end
|
||||
if energyMax == nil then energyMax = 1 end
|
||||
if energyMax == nil or energyMax == 0 then energyMax = 1 end
|
||||
WriteLn(" Energy = " .. math.floor(energy / energyMax * 100) .. " % (" .. energy .. "EU)")
|
||||
local playersString, playersArray = ship.getAttachedPlayers()
|
||||
if playersString == "" then players = "-" end
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1 @@
|
|||
{reboot=true}
|
|
@ -0,0 +1,12 @@
|
|||
alias l="ls -lhp"
|
||||
alias ..="cd .."
|
||||
alias df="df -h"
|
||||
|
||||
alias grep="grep --color"
|
||||
|
||||
# WarpDrive added stuff starts here
|
||||
|
||||
alias ll="ls -lhp"
|
||||
|
||||
# mimic CC autoboot
|
||||
/startup
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,393 @@
|
|||
|
||||
package.loaded.warpdriveCommons = nil
|
||||
local w = require("warpdriveCommons")
|
||||
|
||||
----------- Accelerator support
|
||||
|
||||
local lhc_isEnabled = false
|
||||
local lhc_controlPoints = {}
|
||||
local lhc_parameters = {}
|
||||
local accelerator = nil
|
||||
|
||||
function lhc_boot(isDetailed)
|
||||
if accelerator == nil then
|
||||
return
|
||||
end
|
||||
|
||||
if isDetailed == nil then
|
||||
isDetailed = true
|
||||
end
|
||||
|
||||
if isDetailed then
|
||||
w.write("Booting Accelerator controller")
|
||||
|
||||
w.writeLn("...")
|
||||
w.sleep(0.1)
|
||||
end
|
||||
|
||||
-- getting control points
|
||||
lhc_controlPoints = {}
|
||||
local count = accelerator.getControlPointsCount()
|
||||
lhc_controlChannels = { }
|
||||
countParameters = 0
|
||||
|
||||
if count ~= nil and count > 0 then
|
||||
for i = 0, count - 1 do
|
||||
local success, x, y, z, tier, type, isEnabled, controlChannel = accelerator.getControlPoint(i)
|
||||
if success then
|
||||
if isDetailed then
|
||||
w.write(type .. " " .. tier .. " #" .. controlChannel .. " @ (" .. w.format_integer(x, 6) .. " " .. w.format_integer(y, 3) .. " " .. w.format_integer(z, 6) .. ") ")
|
||||
if isEnabled then
|
||||
w.writeLn("Enabled")
|
||||
else
|
||||
w.writeLn("Disabled")
|
||||
end
|
||||
end
|
||||
lhc_controlPoints[i + 1] = { x, y, z, tier, type, isEnabled, controlChannel }
|
||||
lhc_controlChannels[controlChannel] = "true"
|
||||
countParameters = countParameters + 1
|
||||
elseif isDetailed then
|
||||
w.setColorWarning();
|
||||
w.writeLn("Error " .. x)
|
||||
w.setColorNormal();
|
||||
w.sleep(0.5)
|
||||
end
|
||||
end
|
||||
elseif isDetailed then
|
||||
w.setColorWarning();
|
||||
w.writeLn("No control point detected!")
|
||||
w.sleep(0.5)
|
||||
end
|
||||
|
||||
-- getting parameters
|
||||
local controlChannels = { accelerator.getParametersControlChannels() }
|
||||
if controlChannels ~= nil and #controlChannels > 0 then
|
||||
for key, value in pairs(controlChannels) do lhc_controlChannels[value] = { } end
|
||||
countParameters = countParameters + 1
|
||||
end
|
||||
lhc_parameters = {}
|
||||
if isDetailed then w.sleep(0.1) end
|
||||
|
||||
if countParameters ~= 0 then
|
||||
local index = 1
|
||||
for controlChannel, _ in pairs(lhc_controlChannels) do
|
||||
local success, controlChannelCheck, isEnabled, threshold, description = accelerator.parameter(controlChannel)
|
||||
if success ~= nil and success then
|
||||
if isDetailed then
|
||||
w.write("#" .. w.format_integer(controlChannelCheck, 9) .. " ")
|
||||
if isEnabled then
|
||||
w.write("Enabled")
|
||||
else
|
||||
w.write("Disabled")
|
||||
end
|
||||
w.writeLn(" " .. w.format_integer(threshold * 100, 3) .. "% '" .. description .. "'")
|
||||
end
|
||||
lhc_parameters[index] = { controlChannel, isEnabled, threshold, description }
|
||||
index = index + 1
|
||||
elseif isDetailed then
|
||||
w.setColorWarning();
|
||||
if controlChannelCheck ~= nil then
|
||||
w.writeLn("Error " .. controlChannelCheck)
|
||||
else
|
||||
w.writeLn("Error nil?")
|
||||
end
|
||||
w.sleep(0.5)
|
||||
w.setColorNormal();
|
||||
end
|
||||
if controlChannel ~= controlChannelCheck and isDetailed then
|
||||
w.setColorWarning();
|
||||
w.writeLn("Error: requested " .. controlChannel .. ", received " .. controlChannelCheck)
|
||||
w.sleep(0.5)
|
||||
w.setColorNormal();
|
||||
end
|
||||
end
|
||||
elseif isDetailed then
|
||||
w.setColorWarning();
|
||||
w.writeLn("No control channel detected!")
|
||||
w.sleep(0.5)
|
||||
end
|
||||
end
|
||||
|
||||
function lhc_page_parameter()
|
||||
w.page_begin("<==== Change accelerator parameter ====>")
|
||||
local _, indexSelected = lhc_parameter_getIndexes()
|
||||
local controlChannel, isEnabled, threshold, description = lhc_parameter_get(indexSelected)
|
||||
w.writeLn("Control channel #" .. w.format_integer(controlChannel, 9) .. " applies to:")
|
||||
for key, controlPoint in ipairs(lhc_controlPoints) do
|
||||
local cp_x, cp_y, cp_z, cp_tier, cp_type, cp_isEnabled, cp_controlChannel = unpack(controlPoint)
|
||||
if cp_controlChannel == controlChannel then
|
||||
w.write(string.format("%s %s @%s %s %s ",
|
||||
w.format_string(cp_type, 10),
|
||||
w.format_string(cp_tier, 1),
|
||||
w.format_integer(cp_x, 7), w.format_integer(cp_y, 3), w.format_integer(cp_z, 7) ))
|
||||
if isEnabled then
|
||||
w.writeLn("Enabled")
|
||||
else
|
||||
w.writeLn("Disabled")
|
||||
end
|
||||
end
|
||||
end
|
||||
w.writeLn("")
|
||||
w.writeLn("Current description is '" .. description .. "'")
|
||||
w.write("Enter a description: ")
|
||||
description = w.input_readText(description)
|
||||
|
||||
w.writeLn("")
|
||||
w.writeLn("Current theshold is " .. (threshold * 100) .. "%")
|
||||
w.write("Enter parameter threshold: ")
|
||||
local new_threshold = w.input_readNumber(threshold * 100) / 100
|
||||
threshold = math.min(2.0, math.max(0.0, new_threshold))
|
||||
lhc_parameters[indexSelected] = { controlChannel, isEnabled, threshold, description }
|
||||
accelerator.parameter(controlChannel, isEnabled, threshold, description)
|
||||
end
|
||||
|
||||
lhc_parameter_indexSelected = 1
|
||||
lhc_parameter_indexFirstLine = 1
|
||||
lhc_parameter_lines = 7
|
||||
function lhc_parameter_getIndexes()
|
||||
if lhc_parameters ~= nil then
|
||||
if lhc_parameter_indexSelected > #lhc_parameters then
|
||||
lhc_parameter_indexSelected = 1
|
||||
elseif lhc_parameter_indexSelected < 1 then
|
||||
lhc_parameter_indexSelected = #lhc_parameters
|
||||
end
|
||||
if lhc_parameter_indexFirstLine > lhc_parameter_indexSelected then
|
||||
lhc_parameter_indexFirstLine = lhc_parameter_indexSelected
|
||||
elseif lhc_parameter_indexFirstLine + lhc_parameter_lines < lhc_parameter_indexSelected then
|
||||
lhc_parameter_indexFirstLine = lhc_parameter_indexSelected - lhc_parameter_lines
|
||||
end
|
||||
return lhc_parameter_indexFirstLine, lhc_parameter_indexSelected
|
||||
else
|
||||
return 1, 1
|
||||
end
|
||||
end
|
||||
|
||||
function lhc_parameter_get(index)
|
||||
local parameter = lhc_parameters[index]
|
||||
local controlChannel, isEnabled, threshold, description = -1, false, 0, "-"
|
||||
if parameter == nil or #parameter ~= 4 then
|
||||
lhc_boot(false)
|
||||
w.status_showWarning("Invalid parameter at index " .. index)
|
||||
else
|
||||
controlChannel, isEnabled, threshold, description = unpack(parameter)
|
||||
end
|
||||
return controlChannel, isEnabled, threshold, description
|
||||
end
|
||||
|
||||
function lhc_parameter_updateThreshold(offset)
|
||||
if lhc_parameters ~= nil and offset ~= nil then
|
||||
local _, indexSelected = lhc_parameter_getIndexes()
|
||||
local controlChannel, isEnabled, threshold, description = lhc_parameter_get(indexSelected)
|
||||
threshold = math.min(2.0, math.max(0.0, threshold + offset / 100))
|
||||
lhc_parameters[indexSelected] = { controlChannel, isEnabled, threshold, description }
|
||||
accelerator.parameter(controlChannel, isEnabled, threshold, description)
|
||||
end
|
||||
end
|
||||
|
||||
function lhc_parameter_toggleEnable(forced)
|
||||
if lhc_parameters ~= nil then
|
||||
local _, index = lhc_parameter_getIndexes()
|
||||
local controlChannel, isEnabled, threshold, description = lhc_parameter_get(index)
|
||||
if forced == nil then
|
||||
isEnabled = not isEnabled
|
||||
else
|
||||
isEnabled = forced
|
||||
end
|
||||
lhc_parameters[index] = { controlChannel, isEnabled, threshold, description }
|
||||
accelerator.parameter(controlChannel, isEnabled, threshold, description)
|
||||
end
|
||||
end
|
||||
|
||||
function lhc_page()
|
||||
w.page_begin(w.data_getName() .. " - Accelerator controller")
|
||||
if accelerator ~= nil then
|
||||
-- w.writeLn("")
|
||||
local status, isEnabled, isPowered, energy, temperatureCurrent_K, temperatureTarget_K = accelerator.state()
|
||||
if status == nil then
|
||||
lhc_boot(false)
|
||||
w.status_showWarning("Invalid accelerator status, rebooting...")
|
||||
status, isEnabled, isPowered, energy, temperatureCurrent_K, temperatureTarget_K = "-", false, false, 0, 0, 0
|
||||
end
|
||||
w.writeLn("Accelerator status: " .. status)
|
||||
|
||||
w.write(" Controller is ")
|
||||
if isEnabled then
|
||||
w.setColorGood();
|
||||
w.writeLn("Enabled")
|
||||
else
|
||||
w.setColorBad();
|
||||
w.writeLn("Disabled")
|
||||
end
|
||||
|
||||
local energy, energyMax = accelerator.energy()
|
||||
if energy == nil then energy = 0 end
|
||||
if energyMax == nil or energyMax == 0 then energyMax = 1 end
|
||||
w.setColorNormal();
|
||||
w.write(" Energy level is ")
|
||||
if isPowered then
|
||||
w.setColorGood();
|
||||
elseif isEnabled then
|
||||
w.setColorBad();
|
||||
else
|
||||
w.setColorDisabled();
|
||||
end
|
||||
w.writeLn(math.floor(energy / energyMax * 100) .. " % (" .. energy .. "EU)")
|
||||
-- w.writeLn("")
|
||||
|
||||
w.setColorNormal();
|
||||
w.write(" Magnets temperature is ")
|
||||
if temperatureCurrent_K <= temperatureTarget_K then
|
||||
w.setColorGood();
|
||||
elseif isEnabled then
|
||||
w.setColorBad();
|
||||
else
|
||||
w.setColorDisabled();
|
||||
end
|
||||
w.write(string.format("%fK", math.floor(temperatureCurrent_K * 10) / 10))
|
||||
w.setColorNormal();
|
||||
w.writeLn(". Target is " .. temperatureTarget_K .. "K")
|
||||
-- w.writeLn("")
|
||||
|
||||
w.write("Parameters: ")
|
||||
if #lhc_parameters == 0 then
|
||||
w.setColorDisabled();
|
||||
w.writeLn("")
|
||||
w.writeCentered(" -no valid node detected-")
|
||||
else
|
||||
local indexFirstLine, indexSelected = lhc_parameter_getIndexes()
|
||||
w.writeLn(indexSelected .. "/" .. #lhc_parameters)
|
||||
local indexCurrent = indexFirstLine
|
||||
local indexLastLine = math.min(indexFirstLine + lhc_parameter_lines, #lhc_parameters)
|
||||
for indexCurrent = indexFirstLine, indexLastLine do
|
||||
if indexCurrent == indexSelected then
|
||||
w.setColorSelected()
|
||||
w.clearLine()
|
||||
w.write(">")
|
||||
else
|
||||
w.write(" ")
|
||||
end
|
||||
local controlChannel, isEnabled, threshold, description = lhc_parameter_get(indexCurrent)
|
||||
if description == "-" then
|
||||
description = "#" .. w.format_integer(controlChannel)
|
||||
end
|
||||
w.write(string.format("%s is ",
|
||||
w.format_string(description, 25) ))
|
||||
if isEnabled then
|
||||
w.write("enabled ")
|
||||
else
|
||||
w.write("disabled")
|
||||
end
|
||||
w.writeLn(", set to " .. w.format_integer(threshold * 100, 3) .. "%")
|
||||
w.setColorNormal()
|
||||
end
|
||||
end
|
||||
else
|
||||
w.status_showWarning("No accelerator controller detected")
|
||||
end
|
||||
|
||||
w.setCursorPos(1, 19)
|
||||
w.setColorControl()
|
||||
w.writeFullLine(" Start accelerator (S), Stop accelerator (P)")
|
||||
w.writeFullLine(" Select parameter (Up, Down), Enable parameter (E)")
|
||||
w.writeFullLine(" Change parameter (Enter), Adjust threshold (+, -)")
|
||||
end
|
||||
|
||||
function lhc_key(character, keycode)
|
||||
if character == 's' or character == 'S' then
|
||||
if accelerator ~= nil then
|
||||
accelerator.enable(true)
|
||||
else
|
||||
w.status_showWarning("No accelerator detected")
|
||||
end
|
||||
return true
|
||||
elseif character == 'p' or character == 'P' then
|
||||
if accelerator ~= nil then
|
||||
accelerator.enable(false)
|
||||
else
|
||||
w.status_showWarning("No accelerator detected")
|
||||
end
|
||||
return true
|
||||
elseif keycode == 200 or keycode == 203 then -- Up or Left arrow
|
||||
lhc_parameter_indexSelected = lhc_parameter_indexSelected - 1
|
||||
return true
|
||||
elseif keycode == 208 or keycode == 205 then -- Down or Right arrow
|
||||
lhc_parameter_indexSelected = lhc_parameter_indexSelected + 1
|
||||
return true
|
||||
elseif keycode == 28 or character == 'c' or character == 'C' then -- Return or Enter
|
||||
lhc_page_parameter()
|
||||
return true
|
||||
elseif character == '-' then
|
||||
lhc_parameter_updateThreshold(-1)
|
||||
return true
|
||||
elseif character == '+' then
|
||||
lhc_parameter_updateThreshold(1)
|
||||
return true
|
||||
elseif character == 'e' or character == 'E' or character == ' ' then
|
||||
lhc_parameter_toggleEnable()
|
||||
lhc_parameter_indexSelected = lhc_parameter_indexSelected + 1
|
||||
return true
|
||||
elseif character == 'y' or character == 'Y' then
|
||||
lhc_parameter_toggleEnable(true)
|
||||
lhc_parameter_indexSelected = lhc_parameter_indexSelected + 1
|
||||
return true
|
||||
elseif character == 'n' or character == 'N' then
|
||||
lhc_parameter_toggleEnable(false)
|
||||
lhc_parameter_indexSelected = lhc_parameter_indexSelected + 1
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function lhc_register()
|
||||
w.device_register("warpdriveAccelerator",
|
||||
function(deviceType, address, wrap) accelerator = wrap end,
|
||||
function() end)
|
||||
w.event_register("particleBunchCollided" , function() w.status_showSuccess("Particle bunch have collided") return false end )
|
||||
w.event_register("particleBunchInjected" , function() w.status_showSuccess("Particle bunch injection done") return false end )
|
||||
w.event_register("acceleratorCoolingReset", function() w.status_showWarning("Accelerator coolant has leaked! restarting...") return true end )
|
||||
w.event_register("acceleratorCoolingDone" , function() w.status_showSuccess("Accelerator cooling completed") return true end )
|
||||
w.event_register("acceleratorUpdated" , function() w.status_showSuccess("Accelerator updated") lhc_boot(false) return true end )
|
||||
end
|
||||
|
||||
----------- connections status
|
||||
|
||||
function connections_page(isBooting)
|
||||
w.page_begin(w.data_getName() .. " - Connections")
|
||||
|
||||
w.writeLn("")
|
||||
|
||||
if accelerator == nil then
|
||||
w.setColorDisabled()
|
||||
w.writeLn("No accelerator controller detected")
|
||||
else
|
||||
w.setColorSuccess()
|
||||
w.writeLn("Accelerator controller detected")
|
||||
lhc_boot(isBooting)
|
||||
end
|
||||
|
||||
w.writeLn("")
|
||||
w.setColorNormal()
|
||||
w.writeLn("This is a keyboard controlled user interface.")
|
||||
w.write("Key controls are written like so: ")
|
||||
w.setColorControl()
|
||||
w.write("Action (key)")
|
||||
w.setColorNormal()
|
||||
w.writeLn(".")
|
||||
w.write("For example, typing ")
|
||||
w.setColorControl()
|
||||
w.write(" 1 ")
|
||||
w.setColorNormal()
|
||||
w.writeLn(" will open Accelerator")
|
||||
w.writeLn("controls.")
|
||||
end
|
||||
|
||||
----------- Boot sequence
|
||||
|
||||
w.page_setEndText(" Home (0), Accelerator controls (1)")
|
||||
w.page_register('0', connections_page, nil)
|
||||
w.page_register('1', lhc_page, lhc_key)
|
||||
lhc_register()
|
||||
|
||||
w.boot()
|
||||
w.run()
|
||||
w.close()
|
|
@ -1,887 +0,0 @@
|
|||
local component = require("component")
|
||||
local computer = require("computer")
|
||||
local term = require("term")
|
||||
local event = require("event")
|
||||
local fs = require("filesystem")
|
||||
local serialization = require("serialization")
|
||||
|
||||
if not term.isAvailable() then
|
||||
computer.beep()
|
||||
return
|
||||
end
|
||||
|
||||
Style = {
|
||||
CDefault = 0xFFFFFF,
|
||||
BGDefault = 0x0000FF,
|
||||
|
||||
CTitle = 0x000000,
|
||||
BGTitle = 0x00FFFF,
|
||||
|
||||
CWarning = 0xFFFFFF,
|
||||
BGWarning = 0xFF0000,
|
||||
|
||||
CSuccess = 0xFFFFFF,
|
||||
BGSuccess = 0x32CD32,
|
||||
|
||||
CDisabled = 0x808080,
|
||||
BGDisabled = 0x0000FF
|
||||
}
|
||||
|
||||
----------- Monitor support
|
||||
|
||||
-- cache colors to reduce GPU load
|
||||
local gpu_frontColor = 0xFFFFFF
|
||||
local gpu_backgroundColor = 0x000000
|
||||
function SetMonitorColorFrontBack(frontColor, backgroundColor)
|
||||
if gpu_frontColor ~= frontColor then
|
||||
gpu_frontColor = frontColor
|
||||
component.gpu.setForeground(gpu_frontColor)
|
||||
end
|
||||
if gpu_backgroundColor ~= backgroundColor then
|
||||
gpu_backgroundColor = backgroundColor
|
||||
component.gpu.setBackground(gpu_backgroundColor)
|
||||
end
|
||||
end
|
||||
|
||||
function Write(text)
|
||||
if term.isAvailable() then
|
||||
local w, h = component.gpu.getResolution()
|
||||
if w then
|
||||
local xt, yt = term.getCursor()
|
||||
component.gpu.set(xt, yt, text)
|
||||
SetCursorPos(xt + #text, yt)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SetCursorPos(x, y)
|
||||
if term.isAvailable() then
|
||||
term.setCursor(x, y)
|
||||
end
|
||||
end
|
||||
|
||||
function SetColorDefault()
|
||||
SetMonitorColorFrontBack(Style.CDefault, Style.BGDefault)
|
||||
end
|
||||
|
||||
function SetColorTitle()
|
||||
SetMonitorColorFrontBack(Style.CTitle, Style.BGTitle)
|
||||
end
|
||||
|
||||
function SetColorWarning()
|
||||
SetMonitorColorFrontBack(Style.CWarning, Style.BGWarning)
|
||||
end
|
||||
|
||||
function SetColorSuccess()
|
||||
SetMonitorColorFrontBack(Style.CSuccess, Style.BGSuccess)
|
||||
end
|
||||
|
||||
function SetColorDisabled()
|
||||
SetMonitorColorFrontBack(Style.CDisabled, Style.BGDisabled)
|
||||
end
|
||||
|
||||
function Clear()
|
||||
clearWarningTick = -1
|
||||
SetColorDefault()
|
||||
term.clear()
|
||||
SetCursorPos(1, 1)
|
||||
end
|
||||
|
||||
function ClearLine()
|
||||
SetColorDefault()
|
||||
term.clearLine()
|
||||
SetCursorPos(1, 1)
|
||||
end
|
||||
|
||||
function WriteLn(text)
|
||||
if term.isAvailable() then
|
||||
Write(text)
|
||||
local x, y = term.getCursor()
|
||||
local width, height = component.gpu.getResolution()
|
||||
if y > height - 1 then
|
||||
y = 1
|
||||
end
|
||||
SetCursorPos(1, y + 1)
|
||||
end
|
||||
end
|
||||
|
||||
function WriteCentered(y, text)
|
||||
if term.isAvailable() then
|
||||
local sizeX, sizeY = component.gpu.getResolution()
|
||||
if sizeX then
|
||||
component.gpu.set((sizeX - text:len()) / 2, y, text)
|
||||
end
|
||||
local xt, yt = term.getCursor()
|
||||
SetCursorPos(1, yt + 1)
|
||||
end
|
||||
end
|
||||
|
||||
function ShowTitle(text)
|
||||
Clear()
|
||||
SetColorTitle()
|
||||
WriteCentered(1, text)
|
||||
SetColorDefault()
|
||||
end
|
||||
|
||||
function ShowMenu(text)
|
||||
if term.isAvailable() then
|
||||
Write(text)
|
||||
local sizeX, sizeY = component.gpu.getResolution()
|
||||
local xt, yt = term.getCursor()
|
||||
for i = xt, sizeX do
|
||||
Write(" ")
|
||||
end
|
||||
SetCursorPos(1, yt + 1)
|
||||
end
|
||||
end
|
||||
|
||||
local clearWarningTick = -1
|
||||
function ShowWarning(text)
|
||||
if term.isAvailable() then
|
||||
local sizeX, sizeY = component.gpu.getResolution()
|
||||
SetCursorPos(1, sizeY)
|
||||
ClearLine()
|
||||
SetColorWarning()
|
||||
SetCursorPos((sizeX - text:len() - 2) / 2, sizeY)
|
||||
Write(" " .. text .. " ")
|
||||
SetColorDefault()
|
||||
clearWarningTick = 5
|
||||
end
|
||||
end
|
||||
function ClearWarning()
|
||||
if clearWarningTick > 0 then
|
||||
clearWarningTick = clearWarningTick - 1
|
||||
elseif clearWarningTick == 0 then
|
||||
if term.isAvailable() then
|
||||
SetColorDefault()
|
||||
local sizeX, sizeY = component.gpu.getResolution()
|
||||
SetCursorPos(1, sizeY)
|
||||
ClearLine()
|
||||
clearWarningTick = -1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
----------- Formatting & popups
|
||||
|
||||
function FormatFloat(value, nbchar)
|
||||
local str = "?"
|
||||
if value ~= nil then
|
||||
str = string.format("%g", value)
|
||||
end
|
||||
if nbchar ~= nil then
|
||||
str = string.sub(" " .. str, -nbchar)
|
||||
end
|
||||
return str
|
||||
end
|
||||
function FormatInteger(value, nbchar)
|
||||
local str = "?"
|
||||
if value ~= nil then
|
||||
str = string.format("%d", value)
|
||||
end
|
||||
if nbchar ~= nil then
|
||||
str = string.sub(" " .. str, -nbchar)
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
function boolToYesNo(bool)
|
||||
if bool then
|
||||
return "YES"
|
||||
else
|
||||
return "no"
|
||||
end
|
||||
end
|
||||
|
||||
function readInputNumber(currentValue)
|
||||
local inputAbort = false
|
||||
local input = string.format(currentValue)
|
||||
if input == "0" then
|
||||
input = ""
|
||||
end
|
||||
local x, y = term.getCursor()
|
||||
repeat
|
||||
ClearWarning()
|
||||
SetColorDefault()
|
||||
SetCursorPos(x, y)
|
||||
Write(input .. " ")
|
||||
input = string.sub(input, -9)
|
||||
|
||||
local params = { event.pull() }
|
||||
local eventName = params[1]
|
||||
local address = params[2]
|
||||
if address == nil then address = "none" end
|
||||
if eventName == "key_down" then
|
||||
local char = params[3]
|
||||
local keycode = params[4]
|
||||
if char >= 49 and char <= 57 then -- 1 to 9
|
||||
input = input .. string.format(char - 48)
|
||||
elseif keycode >= 2 and keycode <= 10 then -- 1 to 9
|
||||
input = input .. string.format(keycode - 1)
|
||||
elseif char == 48 or keycode == 11 then -- 0
|
||||
input = input .. "0"
|
||||
elseif char == 45 or char == 78 or char == 110
|
||||
or keycode == 74 or keycode == 12 or keycode == 49 then -- - on numeric keypad or - on US top or n letter
|
||||
if string.sub(input, 1, 1) == "-" then
|
||||
input = string.sub(input, 2)
|
||||
else
|
||||
input = "-" .. input
|
||||
end
|
||||
elseif char == 43 or keycode == 78 then -- +
|
||||
if string.sub(input, 1, 1) == "-" then
|
||||
input = string.sub(input, 2)
|
||||
end
|
||||
elseif char == 8 then -- Backspace
|
||||
input = string.sub(input, 1, string.len(input) - 1)
|
||||
elseif char == 0 and keycode == 211 then -- Delete
|
||||
input = ""
|
||||
elseif char == 13 then -- Enter
|
||||
inputAbort = true
|
||||
elseif char ~= 0 then
|
||||
ShowWarning("Key " .. char .. " " .. keycode .. " is invalid")
|
||||
end
|
||||
elseif eventName == "interrupted" then
|
||||
inputAbort = true
|
||||
elseif not common_event(eventName, params[3]) then
|
||||
ShowWarning("Event '" .. eventName .. "', " .. address .. " is unsupported")
|
||||
end
|
||||
until inputAbort
|
||||
SetCursorPos(1, y + 1)
|
||||
if input == "" or input == "-" then
|
||||
return currentValue
|
||||
else
|
||||
return tonumber(input)
|
||||
end
|
||||
end
|
||||
|
||||
function readInputText(currentValue)
|
||||
local inputAbort = false
|
||||
local input = string.format(currentValue)
|
||||
local x, y = term.getCursor()
|
||||
repeat
|
||||
ClearWarning()
|
||||
SetColorDefault()
|
||||
SetCursorPos(x, y)
|
||||
Write(input .. " ")
|
||||
input = string.sub(input, -30)
|
||||
|
||||
local params = { event.pull() }
|
||||
local eventName = params[1]
|
||||
local address = params[2]
|
||||
if address == nil then address = "none" end
|
||||
if eventName == "key_down" then
|
||||
local char = params[3]
|
||||
local keycode = params[4]
|
||||
if char >= 32 and char <= 127 then -- any ASCII table minus controls and DEL
|
||||
input = input .. string.char(char)
|
||||
elseif char == 8 then -- Backspace
|
||||
input = string.sub(input, 1, string.len(input) - 1)
|
||||
elseif char == 0 and keycode == 211 then -- Delete
|
||||
input = ""
|
||||
elseif char == 13 then -- Enter
|
||||
inputAbort = true
|
||||
elseif char ~= 0 then
|
||||
ShowWarning("Key " .. char .. " " .. keycode .. " is invalid")
|
||||
end
|
||||
elseif eventName == "interrupted" then
|
||||
inputAbort = true
|
||||
elseif not common_event(eventName, params[3]) then
|
||||
ShowWarning("Event '" .. eventName .. "', " .. address .. " is unsupported")
|
||||
end
|
||||
until inputAbort
|
||||
SetCursorPos(1, y + 1)
|
||||
if input == "" then
|
||||
return currentValue
|
||||
else
|
||||
return input
|
||||
end
|
||||
end
|
||||
|
||||
function readConfirmation(msg)
|
||||
if msg == nil then
|
||||
ShowWarning("Are you sure? (y/n)")
|
||||
else
|
||||
ShowWarning(msg)
|
||||
end
|
||||
repeat
|
||||
local params = { event.pull() }
|
||||
local eventName = params[1]
|
||||
local address = params[3]
|
||||
if address == nil then address = "none" end
|
||||
if eventName == "key_down" then
|
||||
local char = params[3]
|
||||
if char == 89 or char == 121 or keycode == 21 then -- Y
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
elseif eventName == "interrupted" then
|
||||
return false
|
||||
elseif not common_event(eventName, params[3]) then
|
||||
ShowWarning("Event '" .. eventName .. "', " .. address .. " is unsupported")
|
||||
end
|
||||
until false
|
||||
end
|
||||
|
||||
----------- commons: menu, event handlers, etc.
|
||||
|
||||
function common_event(eventName, param)
|
||||
if eventName == "redstone" then
|
||||
-- redstone_event(param)
|
||||
elseif eventName == "timer" then
|
||||
elseif eventName == "reactorPulse" then
|
||||
reactor_pulse(param)
|
||||
elseif eventName == "reactorDeactivation" then
|
||||
ShowWarning("Reactor deactivated")
|
||||
elseif eventName == "reactorActivation" then
|
||||
ShowWarning("Reactor activated")
|
||||
elseif eventName == "key_up" then
|
||||
elseif eventName == "touch" then
|
||||
elseif eventName == "drop" then
|
||||
elseif eventName == "drag" then
|
||||
elseif eventName == "component_added" then
|
||||
elseif eventName == "component_removed" then
|
||||
elseif eventName == "component_unavailable" then
|
||||
-- ShowWarning("Event '" .. eventName .. "', " .. param .. " is unsupported")
|
||||
else
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function menu_common()
|
||||
SetCursorPos(1, 23)
|
||||
SetColorTitle()
|
||||
ShowMenu("0 Connections, 1 Reactor, X Exit")
|
||||
end
|
||||
|
||||
----------- Configuration
|
||||
|
||||
function data_save()
|
||||
local file = fs.open("/disk/shipdata.txt", "w")
|
||||
if file ~= nil then
|
||||
file:write(serialization.serialize(data))
|
||||
file:close()
|
||||
else
|
||||
ShowWarning("No file system")
|
||||
os.sleep(0.1)
|
||||
end
|
||||
end
|
||||
|
||||
function data_read()
|
||||
data = { }
|
||||
if fs.exists("/disk/shipdata.txt") then
|
||||
local file = fs.open("/disk/shipdata.txt", "r")
|
||||
local size = fs.size("/disk/shipdata.txt")
|
||||
local rawData = file:read(size)
|
||||
if rawData ~= nil then
|
||||
data = serialization.unserialize(rawData)
|
||||
end
|
||||
file:close()
|
||||
if data == nil then data = {}; end
|
||||
end
|
||||
if data.reactor_mode == nil then data.reactor_mode = 0; end
|
||||
if data.reactor_rate == nil then data.reactor_rate = 100; end
|
||||
if data.reactor_targetStability == nil then data.reactor_targetStability = 50; end
|
||||
if data.reactor_laserAmount == nil then data.reactor_laserAmount = 10000; end
|
||||
end
|
||||
|
||||
function data_setName()
|
||||
if ship ~= nil then
|
||||
ShowTitle("<==== Set ship name ====>")
|
||||
else
|
||||
ShowTitle("<==== Set name ====>")
|
||||
end
|
||||
|
||||
SetCursorPos(1, 2)
|
||||
Write("Enter ship name: ")
|
||||
label = readInputText(label)
|
||||
-- FIXME os.setComputerLabel(label)
|
||||
if ship ~= nil then
|
||||
ship.coreFrequency(label)
|
||||
end
|
||||
-- FIXME computer.shutdown(true)
|
||||
end
|
||||
|
||||
function string_split(source, sep)
|
||||
local sep = sep or ":"
|
||||
local fields = {}
|
||||
local pattern = string.format("([^%s]+)", sep)
|
||||
source:gsub(pattern, function(c) fields[#fields + 1] = c end)
|
||||
return fields
|
||||
end
|
||||
|
||||
|
||||
----------- Reactor support
|
||||
|
||||
reactor_output = 0
|
||||
|
||||
function reactor_boot()
|
||||
if reactor ~= nil then
|
||||
WriteLn("Booting Reactor...")
|
||||
local isActive, strMode, releaseRate = reactor.active()
|
||||
if strMode == "OFF" then
|
||||
data.reactor_mode = 0
|
||||
elseif strMode == "MANUAL" then
|
||||
data.reactor_mode = 1
|
||||
elseif strMode == "ABOVE" then
|
||||
data.reactor_mode = 2
|
||||
elseif strMode == "RATE" then
|
||||
data.reactor_mode = 3
|
||||
else
|
||||
data.reactor_mode = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function reactor_key(char, keycode)
|
||||
if char == 83 or char == 115 or keycode == 31 then -- S
|
||||
reactor_start()
|
||||
return true
|
||||
elseif char == 80 or char == 112 or keycode == 25 then -- P
|
||||
reactor_stop()
|
||||
return true
|
||||
elseif char == 76 or char == 108 or keycode == 38 then -- L
|
||||
reactor_laser()
|
||||
return true
|
||||
elseif char == 79 or char == 111 or keycode == 24 then -- O
|
||||
data.reactor_mode = (data.reactor_mode + 1) % 4
|
||||
reactor_setMode()
|
||||
data_save()
|
||||
return true
|
||||
elseif char == 71 or char == 103 or keycode == 34 then -- G
|
||||
data.reactor_rate = data.reactor_rate - 1000
|
||||
reactor_setMode()
|
||||
data_save()
|
||||
return true
|
||||
elseif char == 84 or char == 116 or keycode == 20 then -- T
|
||||
data.reactor_rate = data.reactor_rate + 1000
|
||||
reactor_setMode()
|
||||
data_save()
|
||||
return true
|
||||
elseif char == 74 or char == 106 or keycode == 36 then -- J
|
||||
data.reactor_laserAmount = data.reactor_laserAmount - 500
|
||||
reactor_setLaser()
|
||||
data_save()
|
||||
return true
|
||||
elseif char == 85 or char == 117 or keycode == 22 then -- U
|
||||
data.reactor_laserAmount = data.reactor_laserAmount + 500
|
||||
reactor_setLaser()
|
||||
data_save()
|
||||
return true
|
||||
elseif char == 45 or keycode == 74 then -- -
|
||||
data.reactor_targetStability = data.reactor_targetStability - 1
|
||||
reactor_setTargetStability()
|
||||
data_save()
|
||||
return true
|
||||
elseif char == 43 or keycode == 78 then -- +
|
||||
data.reactor_targetStability = data.reactor_targetStability + 1
|
||||
reactor_setTargetStability()
|
||||
data_save()
|
||||
return true
|
||||
elseif char == 67 or char == 99 or keycode == 46 then -- C
|
||||
reactor_config()
|
||||
data_save()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function reactor_page()
|
||||
ShowTitle(label .. " - Reactor status")
|
||||
|
||||
SetCursorPos(1, 2)
|
||||
if reactor == nil then
|
||||
SetColorDisabled()
|
||||
Write("Reactor not detected")
|
||||
else
|
||||
SetColorDefault()
|
||||
Write("Reactor stability")
|
||||
instabilities = { reactor.instability() }
|
||||
for key,instability in pairs(instabilities) do
|
||||
SetCursorPos(12, 2 + key)
|
||||
stability = math.floor((100.0 - instability) * 10) / 10
|
||||
if stability >= data.reactor_targetStability then
|
||||
SetColorSuccess()
|
||||
else
|
||||
SetColorWarning()
|
||||
end
|
||||
Write(FormatFloat(stability, 5) .. " %")
|
||||
end
|
||||
|
||||
SetColorDefault()
|
||||
local energy = { reactor.energy() }
|
||||
SetCursorPos(1, 7)
|
||||
Write("Energy : ")
|
||||
if energy[2] ~= nil then
|
||||
Write(FormatInteger(energy[1], 10) .. " / " .. energy[2] .. " RF +" .. FormatInteger(reactor_output, 5) .. " RF/t")
|
||||
else
|
||||
Write("???")
|
||||
end
|
||||
SetCursorPos(1, 8)
|
||||
Write("Outputing: ")
|
||||
if energy[3] ~= nil then
|
||||
Write(energy[3] .. " RF/t")
|
||||
end
|
||||
|
||||
SetColorDefault()
|
||||
SetCursorPos(1, 9)
|
||||
Write("Activated: ")
|
||||
isActive = reactor.active()
|
||||
if isActive then SetColorSuccess() else SetColorDefault() end
|
||||
Write(boolToYesNo(isActive))
|
||||
end
|
||||
|
||||
if #reactorlasers == 0 then
|
||||
SetColorDisabled()
|
||||
SetCursorPos(30, 2)
|
||||
Write("Lasers not detected")
|
||||
else
|
||||
SetColorDefault()
|
||||
SetCursorPos(30, 2)
|
||||
Write("Lasers")
|
||||
|
||||
for key,reactorlaser in pairs(reactorlasers) do
|
||||
local side = reactorlaser.side
|
||||
if side ~= nil then
|
||||
side = side % 4
|
||||
SetColorDefault()
|
||||
SetCursorPos(4, 3 + side)
|
||||
Write("Side " .. side .. ":")
|
||||
SetCursorPos(30, 3 + side)
|
||||
local energy = reactorlaser.wrap.energy()
|
||||
if not reactorlaser.wrap.hasReactor() then
|
||||
SetColorDisabled()
|
||||
elseif energy > 3 * data.reactor_laserAmount then
|
||||
SetColorSuccess()
|
||||
else
|
||||
SetColorWarning()
|
||||
end
|
||||
Write(FormatInteger(energy, 6))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SetColorDefault()
|
||||
SetCursorPos(1, 10)
|
||||
Write(" -----------------------------------------------")
|
||||
SetCursorPos(1, 11)
|
||||
Write("Output mode : ")
|
||||
if data.reactor_mode == 0 then
|
||||
SetColorDisabled()
|
||||
Write("hold")
|
||||
elseif data.reactor_mode == 1 then
|
||||
Write("manual/unlimited")
|
||||
elseif data.reactor_mode == 2 then
|
||||
Write("surplus above " .. data.reactor_rate .. " RF")
|
||||
else
|
||||
Write("rated at " .. data.reactor_rate .. " RF")
|
||||
end
|
||||
SetColorDefault()
|
||||
SetCursorPos( 1, 12)
|
||||
Write("Target stability: " .. data.reactor_targetStability .. "%")
|
||||
SetCursorPos(30, 12)
|
||||
Write("Laser amount: " .. data.reactor_laserAmount)
|
||||
|
||||
SetColorTitle()
|
||||
SetCursorPos(1, 18)
|
||||
ShowMenu("S - Start reactor, P - Stop reactor, L - Use lasers")
|
||||
SetCursorPos(1, 19)
|
||||
ShowMenu("O - Output mode, C - Configuration")
|
||||
SetCursorPos(1, 20)
|
||||
ShowMenu("+/- - Target stability, U/J - Laser amount")
|
||||
SetCursorPos(1, 21)
|
||||
ShowMenu("G/T - Output rate/threshold")
|
||||
end
|
||||
|
||||
function reactor_setMode()
|
||||
if data.reactor_rate < 1 then
|
||||
data.reactor_rate = 1
|
||||
elseif data.reactor_rate > 100000 then
|
||||
data.reactor_rate = 100000
|
||||
end
|
||||
if reactor ~= nil then
|
||||
if data.reactor_mode == 0 then
|
||||
reactor.release(false)
|
||||
elseif data.reactor_mode == 1 then
|
||||
reactor.release(true)
|
||||
elseif data.reactor_mode == 2 then
|
||||
reactor.releaseAbove(data.reactor_rate)
|
||||
else
|
||||
reactor.releaseRate(data.reactor_rate)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function reactor_setLaser()
|
||||
if data.reactor_laserAmount < 1 then
|
||||
data.reactor_laserAmount = 1
|
||||
elseif data.reactor_laserAmount > 100000 then
|
||||
data.reactor_laserAmount = 100000
|
||||
end
|
||||
end
|
||||
|
||||
function reactor_setTargetStability()
|
||||
if data.reactor_targetStability < 1 then
|
||||
data.reactor_targetStability = 1
|
||||
elseif data.reactor_targetStability > 100 then
|
||||
data.reactor_targetStability = 100
|
||||
end
|
||||
end
|
||||
|
||||
function reactor_start()
|
||||
if reactor ~= nil then
|
||||
reactor_setMode()
|
||||
reactor.active(true)
|
||||
end
|
||||
end
|
||||
|
||||
function reactor_stop()
|
||||
if reactor ~= nil then
|
||||
reactor.active(false)
|
||||
end
|
||||
end
|
||||
|
||||
function reactor_laser(side)
|
||||
for key,reactorlaser in pairs(reactorlasers) do
|
||||
if (side == nil) or (reactorlaser.side == side) then
|
||||
reactorlaser.wrap.stabilize(data.reactor_laserAmount)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local reactor_configPageLoaded = false
|
||||
local reactor_pulseStep = 0
|
||||
function reactor_pulse(output)
|
||||
reactor_output = output
|
||||
if reactor == nil then
|
||||
computer.shutdown(true)
|
||||
end
|
||||
local instabilities = { reactor.instability() }
|
||||
for key,instability in pairs(instabilities) do
|
||||
local stability = 100.0 - instability
|
||||
if stability < data.reactor_targetStability then
|
||||
reactor_laser(key - 1)
|
||||
end
|
||||
end
|
||||
reactor_pulseStep = (reactor_pulseStep + 1) % 6
|
||||
if page == reactor_page and (not reactor_configPageLoaded) then
|
||||
if reactor_pulseStep == 0 then
|
||||
for key,instability in pairs(instabilities) do
|
||||
SetCursorPos(12, 2 + key)
|
||||
stability = math.floor((100.0 - instability) * 10) / 10
|
||||
if stability >= data.reactor_targetStability then
|
||||
SetColorSuccess()
|
||||
else
|
||||
SetColorWarning()
|
||||
end
|
||||
Write(FormatFloat(stability, 5) .. " %")
|
||||
end
|
||||
|
||||
elseif reactor_pulseStep == 2 then
|
||||
SetColorDefault()
|
||||
local energy = { reactor.energy() }
|
||||
SetCursorPos(12, 7)
|
||||
if energy[2] ~= nil then
|
||||
Write(FormatInteger(energy[1], 10))
|
||||
SetCursorPos(39, 7)
|
||||
Write(FormatInteger(reactor_output, 5))
|
||||
else
|
||||
Write("???")
|
||||
end
|
||||
if energy[3] ~= nil then
|
||||
SetCursorPos(12, 8)
|
||||
Write(energy[3] .. " RF/t ")
|
||||
end
|
||||
|
||||
elseif reactor_pulseStep == 4 then
|
||||
if #reactorlasers ~= 0 then
|
||||
for key,reactorlaser in pairs(reactorlasers) do
|
||||
local side = reactorlaser.side
|
||||
if side ~= nil then
|
||||
side = side % 4
|
||||
SetCursorPos(30, 3 + side)
|
||||
local energy = reactorlaser.wrap.energy()
|
||||
if not reactorlaser.wrap.hasReactor() then
|
||||
SetColorDisabled()
|
||||
elseif energy > 3 * data.reactor_laserAmount then
|
||||
SetColorSuccess()
|
||||
else
|
||||
SetColorWarning()
|
||||
end
|
||||
Write(FormatInteger(energy, 6))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function reactor_config()
|
||||
reactor_configPageLoaded = true
|
||||
ShowTitle(label .. " - Reactor configuration")
|
||||
|
||||
SetCursorPos(1, 2)
|
||||
if reactor == nil then
|
||||
SetColorDisabled()
|
||||
Write("Reactor not detected")
|
||||
else
|
||||
SetColorDefault()
|
||||
SetCursorPos(1, 4)
|
||||
Write("Reactor output rate (" .. data.reactor_rate .. " RF): ")
|
||||
data.reactor_rate = readInputNumber(data.reactor_rate)
|
||||
reactor_setMode()
|
||||
SetCursorPos(1, 5)
|
||||
Write("Reactor output rate set")
|
||||
|
||||
SetCursorPos(1, 7)
|
||||
Write("Laser energy level (" .. data.reactor_laserAmount .. "): ")
|
||||
data.reactor_laserAmount = readInputNumber(data.reactor_laserAmount)
|
||||
reactor_setLaser()
|
||||
SetCursorPos(1, 8)
|
||||
Write("Laser energy level set")
|
||||
|
||||
SetCursorPos(1, 10)
|
||||
Write("Reactor target stability (" .. data.reactor_targetStability .. "%): ")
|
||||
data.reactor_targetStability = readInputNumber(data.reactor_targetStability)
|
||||
reactor_setTargetStability()
|
||||
SetCursorPos(1, 11)
|
||||
Write("Reactor target stability set")
|
||||
end
|
||||
reactor_configPageLoaded = false
|
||||
end
|
||||
|
||||
----------- Boot sequence
|
||||
label = computer.address()
|
||||
if not label then
|
||||
label = "" .. computer.address()
|
||||
end
|
||||
|
||||
-- read configuration
|
||||
data_read()
|
||||
|
||||
-- initial scanning
|
||||
ShowTitle(label .. " - Connecting...")
|
||||
WriteLn("")
|
||||
|
||||
-- clear previous events
|
||||
repeat
|
||||
until event.pull(0) == nil
|
||||
|
||||
reactor = nil
|
||||
reactorlasers = {}
|
||||
for address, componentType in component.list() do
|
||||
os.sleep(0)
|
||||
Write("Checking " .. componentType .. " ")
|
||||
if componentType == "warpdriveEnanReactorCore" then
|
||||
Write("wrapping!")
|
||||
reactor = component.proxy(address)
|
||||
elseif componentType == "warpdriveEnanReactorLaser" then
|
||||
Write("wrapping!")
|
||||
local wrap = component.proxy(address)
|
||||
table.insert(reactorlasers, { side = wrap.side(), wrap = wrap })
|
||||
end
|
||||
WriteLn("")
|
||||
end
|
||||
|
||||
if not computer.address() and reactor ~= nil then
|
||||
data_setName()
|
||||
end
|
||||
|
||||
-- peripherals status
|
||||
function connections_page()
|
||||
ShowTitle(label .. " - Connections")
|
||||
|
||||
WriteLn("")
|
||||
if reactor == nil then
|
||||
SetColorDisabled()
|
||||
WriteLn("No Enantiomorphic reactor detected")
|
||||
else
|
||||
SetColorSuccess()
|
||||
WriteLn("Enantiomorphic reactor detected")
|
||||
end
|
||||
|
||||
if #reactorlasers == 0 then
|
||||
SetColorDisabled()
|
||||
WriteLn("No reactor stabilisation laser detected")
|
||||
elseif #reactorlasers == 1 then
|
||||
SetColorSuccess()
|
||||
WriteLn("1 reactor stabilisation laser detected")
|
||||
else
|
||||
SetColorSuccess()
|
||||
WriteLn(#reactorlasers .. " reactor stabilisation lasers detected")
|
||||
end
|
||||
|
||||
WriteLn("")
|
||||
SetColorTitle()
|
||||
WriteLn("Please refer to below menu for keyboard controls")
|
||||
WriteLn("For example, press 1 to access Reactor page")
|
||||
end
|
||||
|
||||
-- peripheral boot up
|
||||
Clear()
|
||||
connections_page()
|
||||
SetColorDefault()
|
||||
WriteLn("")
|
||||
os.sleep(0)
|
||||
reactor_boot()
|
||||
os.sleep(0)
|
||||
|
||||
-- main loop
|
||||
abort = false
|
||||
refresh = true
|
||||
page = connections_page
|
||||
keyHandler = nil
|
||||
repeat
|
||||
ClearWarning()
|
||||
if refresh then
|
||||
Clear()
|
||||
page()
|
||||
menu_common()
|
||||
refresh = false
|
||||
end
|
||||
params = { event.pull() }
|
||||
eventName = params[1]
|
||||
address = params[2]
|
||||
if address == nil then address = "none" end
|
||||
-- WriteLn("...")
|
||||
-- WriteLn("Event '" .. eventName .. "', " .. address .. ", " .. params[3] .. " received")
|
||||
-- os.sleep(0.2)
|
||||
if eventName == "key_down" then
|
||||
char = params[3]
|
||||
keycode = params[4]
|
||||
if char == 88 or char == 120 or keycode == 45 then -- x for eXit
|
||||
abort = true
|
||||
elseif char == 48 or keycode == 11 or keycode == 82 then -- 0
|
||||
page = connections_page
|
||||
keyHandler = nil
|
||||
refresh = true
|
||||
elseif char == 49 or keycode == 2 or keycode == 79 then -- 1
|
||||
page = reactor_page
|
||||
keyHandler = reactor_key
|
||||
refresh = true
|
||||
elseif keyHandler ~= nil and keyHandler(char, keycode) then
|
||||
refresh = true
|
||||
os.sleep(0)
|
||||
elseif char == 0 then -- control chars
|
||||
refresh = false
|
||||
os.sleep(0)
|
||||
else
|
||||
ShowWarning("Key " .. char .. " " .. keycode .. " is invalid")
|
||||
os.sleep(0.2)
|
||||
end
|
||||
elseif eventName == "interrupted" then
|
||||
abort = true
|
||||
elseif not common_event(eventName, params[3]) then
|
||||
ShowWarning("Event '" .. eventName .. "', " .. address .. " is unsupported")
|
||||
refresh = true
|
||||
os.sleep(0.2)
|
||||
end
|
||||
until abort
|
||||
|
||||
-- clear screens on exit
|
||||
SetMonitorColorFrontBack(0xFFFFFF, 0x000000)
|
||||
term.clear()
|
||||
SetCursorPos(1, 1)
|
||||
WriteLn("Program terminated")
|
||||
WriteLn("Type reboot to restart it")
|
|
@ -0,0 +1,428 @@
|
|||
|
||||
package.loaded.warpdriveCommons = nil
|
||||
local w = require("warpdriveCommons")
|
||||
|
||||
local data
|
||||
|
||||
----------- Reactor support
|
||||
|
||||
local reactor_output = 0
|
||||
local reactor = nil
|
||||
local reactorlasers = {}
|
||||
|
||||
function reactor_read(parData)
|
||||
data = parData
|
||||
if data.reactor_mode == nil then data.reactor_mode = 0 end
|
||||
if data.reactor_rate == nil then data.reactor_rate = 100 end
|
||||
if data.reactor_targetStability == nil then data.reactor_targetStability = 50 end
|
||||
if data.reactor_laserAmount == nil then data.reactor_laserAmount = 10000 end
|
||||
end
|
||||
|
||||
function reactor_boot()
|
||||
if reactor ~= nil then
|
||||
w.writeLn("Booting Reactor...")
|
||||
local isActive, strMode, releaseRate = reactor.active()
|
||||
if strMode == "OFF" then
|
||||
data.reactor_mode = 0
|
||||
elseif strMode == "MANUAL" then
|
||||
data.reactor_mode = 1
|
||||
elseif strMode == "ABOVE" then
|
||||
data.reactor_mode = 2
|
||||
elseif strMode == "RATE" then
|
||||
data.reactor_mode = 3
|
||||
else
|
||||
data.reactor_mode = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function reactor_key(character, keycode)
|
||||
if character == 's' or character == 'S' then -- S
|
||||
reactor_start()
|
||||
return true
|
||||
elseif character == 'p' or character == 'P' then -- P
|
||||
reactor_stop()
|
||||
return true
|
||||
elseif character == 'l' or character == 'L' then -- L
|
||||
reactor_laser()
|
||||
return true
|
||||
elseif character == 'o' or character == 'O' then -- O
|
||||
data.reactor_mode = (data.reactor_mode + 1) % 4
|
||||
reactor_setMode()
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 'g' or character == 'G' then -- G
|
||||
data.reactor_rate = data.reactor_rate - 1000
|
||||
reactor_setMode()
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 't' or character == 'T' then -- T
|
||||
data.reactor_rate = data.reactor_rate + 1000
|
||||
reactor_setMode()
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 'j' or character == 'J' then -- J
|
||||
data.reactor_laserAmount = data.reactor_laserAmount - 500
|
||||
reactor_setLaser()
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 'u' or character == 'U' then -- U
|
||||
data.reactor_laserAmount = data.reactor_laserAmount + 500
|
||||
reactor_setLaser()
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == '-' then -- -
|
||||
data.reactor_targetStability = data.reactor_targetStability - 1
|
||||
reactor_setTargetStability()
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == '+' then -- +
|
||||
data.reactor_targetStability = data.reactor_targetStability + 1
|
||||
reactor_setTargetStability()
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 'c' or character == 'C' then -- C
|
||||
reactor_config()
|
||||
w.data_save()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function reactor_page()
|
||||
w.page_begin(w.data_getName() .. " - Reactor status")
|
||||
|
||||
w.setCursorPos(1, 2)
|
||||
if reactor == nil then
|
||||
w.setColorDisabled()
|
||||
w.write("Reactor not detected")
|
||||
else
|
||||
w.setColorNormal()
|
||||
w.write("Reactor stability")
|
||||
local instabilities = { reactor.instability() }
|
||||
for key, instability in pairs(instabilities) do
|
||||
w.setCursorPos(12, 2 + key)
|
||||
local stability = math.floor((100.0 - instability) * 10) / 10
|
||||
if stability >= data.reactor_targetStability then
|
||||
w.setColorSuccess()
|
||||
else
|
||||
w.setColorWarning()
|
||||
end
|
||||
w.write(w.format_float(stability, 5) .. " %")
|
||||
end
|
||||
|
||||
w.setColorNormal()
|
||||
local energy = { reactor.energy() }
|
||||
w.setCursorPos(1, 7)
|
||||
w.write("Energy : ")
|
||||
if energy[2] ~= nil then
|
||||
w.write(w.format_integer(energy[1], 10) .. " / " .. energy[2] .. " RF +" .. w.format_integer(reactor_output, 5) .. " RF/t")
|
||||
else
|
||||
w.write("???")
|
||||
end
|
||||
w.setCursorPos(1, 8)
|
||||
w.write("Outputing: ")
|
||||
if energy[3] ~= nil then
|
||||
w.write(energy[3] .. " RF/t")
|
||||
end
|
||||
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(1, 9)
|
||||
w.write("Activated: ")
|
||||
local isActive = reactor.active()
|
||||
if isActive then w.setColorSuccess() else w.setColorNormal() end
|
||||
w.write(w.format_boolean(isActive, "YES", "no"))
|
||||
end
|
||||
|
||||
if #reactorlasers == 0 then
|
||||
w.setColorDisabled()
|
||||
w.setCursorPos(30, 2)
|
||||
w.write("Lasers not detected")
|
||||
else
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(30, 2)
|
||||
w.write("Lasers")
|
||||
|
||||
for key, reactorlaser in pairs(reactorlasers) do
|
||||
local side = reactorlaser.side
|
||||
if side ~= nil then
|
||||
side = side % 4
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(4, 3 + side)
|
||||
w.write("Side " .. side .. ":")
|
||||
w.setCursorPos(30, 3 + side)
|
||||
local energy = reactorlaser.wrap.energy()
|
||||
if not reactorlaser.wrap.hasReactor() then
|
||||
w.setColorDisabled()
|
||||
elseif energy > 3 * data.reactor_laserAmount then
|
||||
w.setColorSuccess()
|
||||
else
|
||||
w.setColorWarning()
|
||||
end
|
||||
w.write(w.format_integer(energy, 6))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(1, 10)
|
||||
w.write(" -----------------------------------------------")
|
||||
w.setCursorPos(1, 11)
|
||||
w.write("Output mode : ")
|
||||
if data.reactor_mode == 0 then
|
||||
w.setColorDisabled()
|
||||
w.write("hold")
|
||||
elseif data.reactor_mode == 1 then
|
||||
w.write("manual/unlimited")
|
||||
elseif data.reactor_mode == 2 then
|
||||
w.write("surplus above " .. data.reactor_rate .. " RF")
|
||||
else
|
||||
w.write("rated at " .. data.reactor_rate .. " RF")
|
||||
end
|
||||
w.setColorNormal()
|
||||
w.setCursorPos( 1, 12)
|
||||
w.write("Target stability: " .. data.reactor_targetStability .. "%")
|
||||
w.setCursorPos(30, 12)
|
||||
w.write("Laser amount: " .. data.reactor_laserAmount)
|
||||
|
||||
w.setColorControl()
|
||||
w.setCursorPos(1, 18)
|
||||
w.writeFullLine(" Start/stoP reactor (S/P), Use lasers (L)")
|
||||
w.writeFullLine(" Output mode (O), Configuration (C)")
|
||||
w.writeFullLine(" Target stability (+/-), Laser amount (U/J)")
|
||||
w.writeFullLine(" Output rate/threshold (G/T)")
|
||||
end
|
||||
|
||||
function reactor_setMode()
|
||||
if data.reactor_rate < 1 then
|
||||
data.reactor_rate = 1
|
||||
elseif data.reactor_rate > 100000 then
|
||||
data.reactor_rate = 100000
|
||||
end
|
||||
if reactor ~= nil then
|
||||
if data.reactor_mode == 0 then
|
||||
reactor.release(false)
|
||||
elseif data.reactor_mode == 1 then
|
||||
reactor.release(true)
|
||||
elseif data.reactor_mode == 2 then
|
||||
reactor.releaseAbove(data.reactor_rate)
|
||||
else
|
||||
reactor.releaseRate(data.reactor_rate)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function reactor_setLaser()
|
||||
if data.reactor_laserAmount < 1 then
|
||||
data.reactor_laserAmount = 1
|
||||
elseif data.reactor_laserAmount > 100000 then
|
||||
data.reactor_laserAmount = 100000
|
||||
end
|
||||
end
|
||||
|
||||
function reactor_setTargetStability()
|
||||
if data.reactor_targetStability < 1 then
|
||||
data.reactor_targetStability = 1
|
||||
elseif data.reactor_targetStability > 100 then
|
||||
data.reactor_targetStability = 100
|
||||
end
|
||||
end
|
||||
|
||||
function reactor_start()
|
||||
if reactor ~= nil then
|
||||
reactor_setMode()
|
||||
reactor.active(true)
|
||||
end
|
||||
end
|
||||
|
||||
function reactor_stop()
|
||||
if reactor ~= nil then
|
||||
reactor.active(false)
|
||||
end
|
||||
end
|
||||
|
||||
function reactor_laser(side)
|
||||
for key, reactorlaser in pairs(reactorlasers) do
|
||||
if (side == nil) or (reactorlaser.side == side) then
|
||||
reactorlaser.wrap.stabilize(data.reactor_laserAmount)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local reactor_configPageLoaded = false
|
||||
local reactor_pulseStep = 0
|
||||
function reactor_pulse(output)
|
||||
reactor_output = output
|
||||
if reactor == nil then
|
||||
w.reboot()
|
||||
end
|
||||
local instabilities = { reactor.instability() }
|
||||
for key, instability in pairs(instabilities) do
|
||||
local stability = 100.0 - instability
|
||||
if stability < data.reactor_targetStability then
|
||||
reactor_laser(key - 1)
|
||||
end
|
||||
end
|
||||
reactor_pulseStep = (reactor_pulseStep + 1) % 6
|
||||
if w.page_getCallbackDisplay() == reactor_page and (not reactor_configPageLoaded) then
|
||||
if reactor_pulseStep == 0 then
|
||||
for key, instability in pairs(instabilities) do
|
||||
w.setCursorPos(12, 2 + key)
|
||||
stability = math.floor((100.0 - instability) * 10) / 10
|
||||
if stability >= data.reactor_targetStability then
|
||||
w.setColorSuccess()
|
||||
else
|
||||
w.setColorWarning()
|
||||
end
|
||||
w.write(w.format_float(stability, 5) .. " %")
|
||||
end
|
||||
|
||||
elseif reactor_pulseStep == 2 then
|
||||
w.setColorNormal()
|
||||
local energy = { reactor.energy() }
|
||||
w.setCursorPos(12, 7)
|
||||
if energy[2] ~= nil then
|
||||
w.write(w.format_integer(energy[1], 10))
|
||||
w.setCursorPos(39, 7)
|
||||
w.write(w.format_integer(reactor_output, 5))
|
||||
else
|
||||
w.write("???")
|
||||
end
|
||||
if energy[3] ~= nil then
|
||||
w.setCursorPos(12, 8)
|
||||
w.write(energy[3] .. " RF/t ")
|
||||
end
|
||||
|
||||
elseif reactor_pulseStep == 4 then
|
||||
if #reactorlasers ~= 0 then
|
||||
for key, reactorlaser in pairs(reactorlasers) do
|
||||
local side = reactorlaser.side
|
||||
if side ~= nil and reactorlaser.wrap ~= nil then
|
||||
side = side % 4
|
||||
w.setCursorPos(30, 3 + side)
|
||||
local energy = reactorlaser.wrap.energy()
|
||||
if energy == nil then
|
||||
energy = -1
|
||||
end
|
||||
if not reactorlaser.wrap.hasReactor() then
|
||||
w.setColorDisabled()
|
||||
elseif energy > 3 * data.reactor_laserAmount then
|
||||
w.setColorSuccess()
|
||||
else
|
||||
w.setColorWarning()
|
||||
end
|
||||
w.write(w.format_integer(energy, 6))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function reactor_config()
|
||||
reactor_configPageLoaded = true
|
||||
w.page_begin(w.data_getName() .. " - Reactor configuration")
|
||||
|
||||
w.setCursorPos(1, 2)
|
||||
if reactor == nil then
|
||||
w.setColorDisabled()
|
||||
w.write("Reactor not detected")
|
||||
else
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(1, 4)
|
||||
w.write("Reactor output rate (" .. data.reactor_rate .. " RF): ")
|
||||
data.reactor_rate = w.input_readNumber(data.reactor_rate)
|
||||
reactor_setMode()
|
||||
w.setCursorPos(1, 5)
|
||||
w.write("Reactor output rate set")
|
||||
|
||||
w.setCursorPos(1, 7)
|
||||
w.write("Laser energy level (" .. data.reactor_laserAmount .. "): ")
|
||||
data.reactor_laserAmount = w.input_readNumber(data.reactor_laserAmount)
|
||||
reactor_setLaser()
|
||||
w.setCursorPos(1, 8)
|
||||
w.write("Laser energy level set")
|
||||
|
||||
w.setCursorPos(1, 10)
|
||||
w.write("Reactor target stability (" .. data.reactor_targetStability .. "%): ")
|
||||
data.reactor_targetStability = w.input_readNumber(data.reactor_targetStability)
|
||||
reactor_setTargetStability()
|
||||
w.setCursorPos(1, 11)
|
||||
w.write("Reactor target stability set")
|
||||
end
|
||||
reactor_configPageLoaded = false
|
||||
end
|
||||
|
||||
function reactor_register()
|
||||
w.device_register("warpdriveEnanReactorCore",
|
||||
function(deviceType, address, wrap) reactor = wrap end,
|
||||
function() end)
|
||||
w.device_register("warpdriveEnanReactorLaser",
|
||||
function(deviceType, address, wrap) table.insert(reactorlasers, { side = wrap.side(), wrap = wrap }) end,
|
||||
function() end)
|
||||
w.event_register("reactorPulse" , function() reactor_pulse(param) return false end )
|
||||
w.event_register("reactorDeactivation", function() w.status_showWarning("Reactor deactivated") return false end )
|
||||
w.event_register("reactorActivation" , function() w.status_showWarning("Reactor activated") return false end )
|
||||
w.data_register("reactor", reactor_read, nil)
|
||||
end
|
||||
|
||||
----------- connections status
|
||||
|
||||
function connections_page(isBooting)
|
||||
w.page_begin(w.data_getName() .. " - Connections")
|
||||
|
||||
w.writeLn("")
|
||||
|
||||
if reactor == nil then
|
||||
w.setColorDisabled()
|
||||
w.writeLn("No Enantiomorphic reactor detected")
|
||||
else
|
||||
w.setColorSuccess()
|
||||
w.writeLn("Enantiomorphic reactor detected")
|
||||
if isBooting then
|
||||
reactor_boot()
|
||||
end
|
||||
end
|
||||
|
||||
if #reactorlasers == 0 then
|
||||
w.setColorDisabled()
|
||||
w.writeLn("No reactor stabilisation laser detected")
|
||||
elseif #reactorlasers == 1 then
|
||||
w.setColorSuccess()
|
||||
w.writeLn("1 reactor stabilisation laser detected")
|
||||
else
|
||||
w.setColorSuccess()
|
||||
w.writeLn(#reactorlasers .. " reactor stabilisation lasers detected")
|
||||
end
|
||||
|
||||
w.writeLn("")
|
||||
w.setColorNormal()
|
||||
w.writeLn("This is a keyboard controlled user interface.")
|
||||
w.write("Key controls are written like so: ")
|
||||
w.setColorControl()
|
||||
w.write("Action (key)")
|
||||
w.setColorNormal()
|
||||
w.writeLn(".")
|
||||
w.write("For example, typing ")
|
||||
w.setColorControl()
|
||||
w.write(" 1 ")
|
||||
w.setColorNormal()
|
||||
w.writeLn(" will open Reactor controls.")
|
||||
end
|
||||
|
||||
----------- Boot sequence
|
||||
|
||||
w.page_setEndText(" Home (0), Reactor controls (1)")
|
||||
w.page_register('0', connections_page, nil)
|
||||
w.page_register('1', reactor_page, reactor_key)
|
||||
reactor_register()
|
||||
|
||||
w.boot()
|
||||
local success, message = pcall(w.run)
|
||||
if not success then
|
||||
print("failed with message")
|
||||
print(message)
|
||||
print("exiting")
|
||||
else
|
||||
w.close()
|
||||
end
|
|
@ -1,935 +0,0 @@
|
|||
local component = require("component")
|
||||
local computer = require("computer")
|
||||
local term = require("term")
|
||||
local event = require("event")
|
||||
local fs = require("filesystem")
|
||||
local serialization = require("serialization")
|
||||
|
||||
if not term.isAvailable() then
|
||||
computer.beep()
|
||||
return
|
||||
end
|
||||
|
||||
Style = {
|
||||
CDefault = 0xFFFFFF,
|
||||
BGDefault = 0x0000FF,
|
||||
|
||||
CTitle = 0x000000,
|
||||
BGTitle = 0x00FFFF,
|
||||
|
||||
CWarning = 0xFFFFFF,
|
||||
BGWarning = 0xFF0000,
|
||||
|
||||
CSuccess = 0xFFFFFF,
|
||||
BGSuccess = 0x32CD32,
|
||||
|
||||
CDisabled = 0x808080,
|
||||
BGDisabled = 0x0000FF
|
||||
}
|
||||
|
||||
----------- Monitor support
|
||||
|
||||
-- cache colors to reduce GPU load
|
||||
local gpu_frontColor = 0xFFFFFF
|
||||
local gpu_backgroundColor = 0x000000
|
||||
function SetMonitorColorFrontBack(frontColor, backgroundColor)
|
||||
if gpu_frontColor ~= frontColor then
|
||||
gpu_frontColor = frontColor
|
||||
component.gpu.setForeground(gpu_frontColor)
|
||||
end
|
||||
if gpu_backgroundColor ~= backgroundColor then
|
||||
gpu_backgroundColor = backgroundColor
|
||||
component.gpu.setBackground(gpu_backgroundColor)
|
||||
end
|
||||
end
|
||||
|
||||
function Write(text)
|
||||
if term.isAvailable() then
|
||||
local w, h = component.gpu.getResolution()
|
||||
if w then
|
||||
local xt, yt = term.getCursor()
|
||||
component.gpu.set(xt, yt, text)
|
||||
SetCursorPos(xt + #text, yt)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SetCursorPos(x, y)
|
||||
if term.isAvailable() then
|
||||
term.setCursor(x, y)
|
||||
end
|
||||
end
|
||||
|
||||
function SetColorDefault()
|
||||
SetMonitorColorFrontBack(Style.CDefault, Style.BGDefault)
|
||||
end
|
||||
|
||||
function SetColorTitle()
|
||||
SetMonitorColorFrontBack(Style.CTitle, Style.BGTitle)
|
||||
end
|
||||
|
||||
function SetColorWarning()
|
||||
SetMonitorColorFrontBack(Style.CWarning, Style.BGWarning)
|
||||
end
|
||||
|
||||
function SetColorSuccess()
|
||||
SetMonitorColorFrontBack(Style.CSuccess, Style.BGSuccess)
|
||||
end
|
||||
|
||||
function SetColorDisabled()
|
||||
SetMonitorColorFrontBack(Style.CDisabled, Style.BGDisabled)
|
||||
end
|
||||
|
||||
function Clear()
|
||||
clearWarningTick = -1
|
||||
SetColorDefault()
|
||||
term.clear()
|
||||
SetCursorPos(1, 1)
|
||||
end
|
||||
|
||||
function ClearLine()
|
||||
SetColorDefault()
|
||||
term.clearLine()
|
||||
SetCursorPos(1, 1)
|
||||
end
|
||||
|
||||
function WriteLn(text)
|
||||
if term.isAvailable() then
|
||||
Write(text)
|
||||
local x, y = term.getCursor()
|
||||
local width, height = component.gpu.getResolution()
|
||||
if y > height - 1 then
|
||||
y = 1
|
||||
end
|
||||
SetCursorPos(1, y + 1)
|
||||
end
|
||||
end
|
||||
|
||||
function WriteCentered(y, text)
|
||||
if term.isAvailable() then
|
||||
local sizeX, sizeY = component.gpu.getResolution()
|
||||
if sizeX then
|
||||
component.gpu.set((sizeX - text:len()) / 2, y, text)
|
||||
end
|
||||
local xt, yt = term.getCursor()
|
||||
SetCursorPos(1, yt + 1)
|
||||
end
|
||||
end
|
||||
|
||||
function ShowTitle(text)
|
||||
Clear()
|
||||
SetColorTitle()
|
||||
WriteCentered(1, text)
|
||||
SetColorDefault()
|
||||
end
|
||||
|
||||
function ShowMenu(text)
|
||||
if term.isAvailable() then
|
||||
Write(text)
|
||||
local sizeX, sizeY = component.gpu.getResolution()
|
||||
local xt, yt = term.getCursor()
|
||||
for i = xt, sizeX do
|
||||
Write(" ")
|
||||
end
|
||||
SetCursorPos(1, yt + 1)
|
||||
end
|
||||
end
|
||||
|
||||
local clearWarningTick = -1
|
||||
function ShowWarning(text)
|
||||
if term.isAvailable() then
|
||||
local sizeX, sizeY = component.gpu.getResolution()
|
||||
SetCursorPos(1, sizeY)
|
||||
ClearLine()
|
||||
SetColorWarning()
|
||||
SetCursorPos((sizeX - text:len() - 2) / 2, sizeY)
|
||||
Write(" " .. text .. " ")
|
||||
SetColorDefault()
|
||||
clearWarningTick = 5
|
||||
end
|
||||
end
|
||||
function ClearWarning()
|
||||
if clearWarningTick > 0 then
|
||||
clearWarningTick = clearWarningTick - 1
|
||||
elseif clearWarningTick == 0 then
|
||||
if term.isAvailable() then
|
||||
SetColorDefault()
|
||||
local sizeX, sizeY = component.gpu.getResolution()
|
||||
SetCursorPos(1, sizeY)
|
||||
ClearLine()
|
||||
clearWarningTick = -1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
----------- Formatting & popups
|
||||
|
||||
function FormatFloat(value, nbchar)
|
||||
local str = "?"
|
||||
if value ~= nil then
|
||||
str = string.format("%g", value)
|
||||
end
|
||||
if nbchar ~= nil then
|
||||
str = string.sub(" " .. str, -nbchar)
|
||||
end
|
||||
return str
|
||||
end
|
||||
function FormatInteger(value, nbchar)
|
||||
local str = "?"
|
||||
if value ~= nil then
|
||||
str = string.format("%d", value)
|
||||
end
|
||||
if nbchar ~= nil then
|
||||
str = string.sub(" " .. str, -nbchar)
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
function boolToYesNo(bool)
|
||||
if bool then
|
||||
return "YES"
|
||||
else
|
||||
return "no"
|
||||
end
|
||||
end
|
||||
|
||||
function readInputNumber(currentValue)
|
||||
local inputAbort = false
|
||||
local input = string.format(currentValue)
|
||||
if input == "0" then
|
||||
input = ""
|
||||
end
|
||||
local x, y = term.getCursor()
|
||||
repeat
|
||||
ClearWarning()
|
||||
SetColorDefault()
|
||||
SetCursorPos(x, y)
|
||||
Write(input .. " ")
|
||||
input = string.sub(input, -9)
|
||||
|
||||
local params = { event.pull() }
|
||||
local eventName = params[1]
|
||||
local address = params[2]
|
||||
if address == nil then address = "none" end
|
||||
if eventName == "key_down" then
|
||||
local char = params[3]
|
||||
local keycode = params[4]
|
||||
if char >= 49 and char <= 57 then -- 1 to 9
|
||||
input = input .. string.format(char - 48)
|
||||
elseif keycode >= 2 and keycode <= 10 then -- 1 to 9
|
||||
input = input .. string.format(keycode - 1)
|
||||
elseif char == 48 or keycode == 11 then -- 0
|
||||
input = input .. "0"
|
||||
elseif char == 45 or char == 78 or char == 110
|
||||
or keycode == 74 or keycode == 12 or keycode == 49 then -- - on numeric keypad or - on US top or n letter
|
||||
if string.sub(input, 1, 1) == "-" then
|
||||
input = string.sub(input, 2)
|
||||
else
|
||||
input = "-" .. input
|
||||
end
|
||||
elseif char == 43 or keycode == 78 then -- +
|
||||
if string.sub(input, 1, 1) == "-" then
|
||||
input = string.sub(input, 2)
|
||||
end
|
||||
elseif char == 8 then -- Backspace
|
||||
input = string.sub(input, 1, string.len(input) - 1)
|
||||
elseif char == 0 and keycode == 211 then -- Delete
|
||||
input = ""
|
||||
elseif char == 13 then -- Enter
|
||||
inputAbort = true
|
||||
elseif char ~= 0 then
|
||||
ShowWarning("Key " .. char .. " " .. keycode .. " is invalid")
|
||||
end
|
||||
elseif eventName == "interrupted" then
|
||||
inputAbort = true
|
||||
elseif not common_event(eventName, params[3]) then
|
||||
ShowWarning("Event '" .. eventName .. "', " .. address .. " is unsupported")
|
||||
end
|
||||
until inputAbort
|
||||
SetCursorPos(1, y + 1)
|
||||
if input == "" or input == "-" then
|
||||
return currentValue
|
||||
else
|
||||
return tonumber(input)
|
||||
end
|
||||
end
|
||||
|
||||
function readInputText(currentValue)
|
||||
local inputAbort = false
|
||||
local input = string.format(currentValue)
|
||||
local x, y = term.getCursor()
|
||||
repeat
|
||||
ClearWarning()
|
||||
SetColorDefault()
|
||||
SetCursorPos(x, y)
|
||||
Write(input .. " ")
|
||||
input = string.sub(input, -30)
|
||||
|
||||
local params = { event.pull() }
|
||||
local eventName = params[1]
|
||||
local address = params[2]
|
||||
if address == nil then address = "none" end
|
||||
if eventName == "key_down" then
|
||||
local char = params[3]
|
||||
local keycode = params[4]
|
||||
if char >= 32 and char <= 127 then -- any ASCII table minus controls and DEL
|
||||
input = input .. string.char(char)
|
||||
elseif char == 8 then -- Backspace
|
||||
input = string.sub(input, 1, string.len(input) - 1)
|
||||
elseif char == 0 and keycode == 211 then -- Delete
|
||||
input = ""
|
||||
elseif char == 13 then -- Enter
|
||||
inputAbort = true
|
||||
elseif char ~= 0 then
|
||||
ShowWarning("Key " .. char .. " " .. keycode .. " is invalid")
|
||||
end
|
||||
elseif eventName == "interrupted" then
|
||||
inputAbort = true
|
||||
elseif not common_event(eventName, params[3]) then
|
||||
ShowWarning("Event '" .. eventName .. "', " .. address .. " is unsupported")
|
||||
end
|
||||
until inputAbort
|
||||
SetCursorPos(1, y + 1)
|
||||
if input == "" then
|
||||
return currentValue
|
||||
else
|
||||
return input
|
||||
end
|
||||
end
|
||||
|
||||
function readConfirmation(msg)
|
||||
if msg == nil then
|
||||
ShowWarning("Are you sure? (y/n)")
|
||||
else
|
||||
ShowWarning(msg)
|
||||
end
|
||||
repeat
|
||||
local params = { event.pull() }
|
||||
local eventName = params[1]
|
||||
local address = params[3]
|
||||
if address == nil then address = "none" end
|
||||
if eventName == "key_down" then
|
||||
local char = params[3]
|
||||
if char == 89 or char == 121 or keycode == 21 then -- Y
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
elseif eventName == "interrupted" then
|
||||
return false
|
||||
elseif not common_event(eventName, params[3]) then
|
||||
ShowWarning("Event '" .. eventName .. "', " .. address .. " is unsupported")
|
||||
end
|
||||
until false
|
||||
end
|
||||
|
||||
----------- commons: menu, event handlers, etc.
|
||||
|
||||
function common_event(eventName, param)
|
||||
if eventName == "redstone" then
|
||||
-- redstone_event(param)
|
||||
elseif eventName == "timer" then
|
||||
elseif eventName == "shipCoreCooldownDone" then
|
||||
ShowWarning("Ship core cooldown done")
|
||||
elseif eventName == "key_up" then
|
||||
elseif eventName == "touch" then
|
||||
elseif eventName == "drop" then
|
||||
elseif eventName == "drag" then
|
||||
elseif eventName == "component_added" then
|
||||
elseif eventName == "component_removed" then
|
||||
elseif eventName == "component_unavailable" then
|
||||
-- ShowWarning("Event '" .. eventName .. "', " .. param .. " is unsupported")
|
||||
else
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function menu_common()
|
||||
SetCursorPos(1, 23)
|
||||
SetColorTitle()
|
||||
ShowMenu("0 Connections, 1 Ship core, X Exit")
|
||||
end
|
||||
|
||||
----------- Configuration
|
||||
|
||||
function data_save()
|
||||
local file = fs.open("/disk/shipdata.txt", "w")
|
||||
if file ~= nil then
|
||||
file:write(serialization.serialize(data))
|
||||
file:close()
|
||||
else
|
||||
ShowWarning("No file system")
|
||||
os.sleep(3)
|
||||
end
|
||||
end
|
||||
|
||||
function data_read()
|
||||
data = { }
|
||||
if fs.exists("/disk/shipdata.txt") then
|
||||
local file = fs.open("/disk/shipdata.txt", "r")
|
||||
local size = fs.size("/disk/shipdata.txt")
|
||||
local rawData = file:read(size)
|
||||
if rawData ~= nil then
|
||||
data = serialization.unserialize(rawData)
|
||||
end
|
||||
file:close()
|
||||
if data == nil then data = {}; end
|
||||
end
|
||||
if data.core_summon == nil then data.core_summon = false; end
|
||||
end
|
||||
|
||||
function data_setName()
|
||||
if ship ~= nil then
|
||||
ShowTitle("<==== Set ship name ====>")
|
||||
else
|
||||
ShowTitle("<==== Set name ====>")
|
||||
end
|
||||
|
||||
SetCursorPos(1, 2)
|
||||
Write("Enter ship name: ")
|
||||
label = readInputText(label)
|
||||
-- FIXME os.setComputerLabel(label)
|
||||
if ship ~= nil then
|
||||
ship.coreFrequency(label)
|
||||
end
|
||||
-- FIXME computer.shutdown(true)
|
||||
end
|
||||
|
||||
function string_split(source, sep)
|
||||
local sep = sep or ":"
|
||||
local fields = {}
|
||||
local pattern = string.format("([^%s]+)", sep)
|
||||
source:gsub(pattern, function(c) fields[#fields + 1] = c end)
|
||||
return fields
|
||||
end
|
||||
|
||||
|
||||
----------- Ship support
|
||||
|
||||
core_front = 0
|
||||
core_right = 0
|
||||
core_up = 0
|
||||
core_back = 0
|
||||
core_left = 0
|
||||
core_down = 0
|
||||
core_isInHyper = false
|
||||
core_jumpCost = 0
|
||||
core_shipSize = 0
|
||||
core_movement = { 0, 0, 0 }
|
||||
core_rotationSteps = 0
|
||||
|
||||
function core_boot()
|
||||
if ship == nil then
|
||||
return
|
||||
end
|
||||
|
||||
Write("Booting Ship Core")
|
||||
|
||||
if data.core_summon then
|
||||
ship.summon_all()
|
||||
end
|
||||
|
||||
WriteLn("...")
|
||||
core_front, core_right, core_up = ship.dim_positive()
|
||||
core_back, core_left, core_down = ship.dim_negative()
|
||||
core_isInHyper = ship.isInHyperspace()
|
||||
core_rotationSteps = ship.rotationSteps()
|
||||
core_movement = { ship.movement() }
|
||||
if ship.direction ~= nil then
|
||||
ship.direction(666)
|
||||
ship.distance(0)
|
||||
end
|
||||
WriteLn("Ship core detected...")
|
||||
|
||||
repeat
|
||||
pos = ship.position()
|
||||
os.sleep(0.3)
|
||||
until pos ~= nil
|
||||
X, Y, Z = ship.position()
|
||||
WriteLn("Ship position triangulated...")
|
||||
|
||||
repeat
|
||||
isAttached = ship.isAttached()
|
||||
os.sleep(0.3)
|
||||
until isAttached ~= false
|
||||
WriteLn("Ship core linked...")
|
||||
|
||||
repeat
|
||||
core_shipSize = ship.getShipSize()
|
||||
os.sleep(0.3)
|
||||
until core_shipSize ~= nil
|
||||
WriteLn("Ship size updated...")
|
||||
|
||||
ship.mode(1)
|
||||
end
|
||||
|
||||
function core_writeMovement()
|
||||
local message = " Movement = "
|
||||
local count = 0
|
||||
if core_movement[1] > 0 then
|
||||
message = message .. core_movement[1] .. " front"
|
||||
count = count + 1
|
||||
elseif core_movement[1] < 0 then
|
||||
message = message .. (- core_movement[1]) .. " back"
|
||||
count = count + 1
|
||||
end
|
||||
if core_movement[2] > 0 then
|
||||
if count > 0 then message = message .. ", "; end
|
||||
message = message .. core_movement[2] .. " up"
|
||||
count = count + 1
|
||||
elseif core_movement[2] < 0 then
|
||||
if count > 0 then message = message .. ", "; end
|
||||
message = message .. (- core_movement[2]) .. " down"
|
||||
count = count + 1
|
||||
end
|
||||
if core_movement[3] > 0 then
|
||||
if count > 0 then message = message .. ", "; end
|
||||
message = message .. core_movement[3] .. " right"
|
||||
count = count + 1
|
||||
elseif core_movement[3] < 0 then
|
||||
if count > 0 then message = message .. ", "; end
|
||||
message = message .. (- core_movement[3]) .. " left"
|
||||
count = count + 1
|
||||
end
|
||||
|
||||
if core_rotationSteps == 1 then
|
||||
if count > 0 then message = message .. ", "; end
|
||||
message = message .. "Turn right"
|
||||
count = count + 1
|
||||
elseif core_rotationSteps == 2 then
|
||||
if count > 0 then message = message .. ", "; end
|
||||
message = message .. "Turn back"
|
||||
count = count + 1
|
||||
elseif core_rotationSteps == 3 then
|
||||
if count > 0 then message = message .. ", "; end
|
||||
message = message .. "Turn left"
|
||||
count = count + 1
|
||||
end
|
||||
|
||||
if count == 0 then
|
||||
message = message .. "(none)"
|
||||
end
|
||||
WriteLn(message)
|
||||
end
|
||||
|
||||
function core_writeRotation()
|
||||
if core_rotationSteps == 0 then
|
||||
WriteLn(" Rotation = Front")
|
||||
elseif core_rotationSteps == 1 then
|
||||
WriteLn(" Rotation = Right +90")
|
||||
elseif core_rotationSteps == 2 then
|
||||
WriteLn(" Rotation = Back 180")
|
||||
elseif core_rotationSteps == 3 then
|
||||
WriteLn(" Rotation = Left -90")
|
||||
end
|
||||
end
|
||||
|
||||
function core_computeNewCoordinates(cx, cy, cz)
|
||||
local res = { x = cx, y = cy, z = cz }
|
||||
local dx, dy, dz = ship.getOrientation()
|
||||
local worldMovement = { x = 0, y = 0, z = 0 }
|
||||
worldMovement.x = dx * core_movement[1] - dz * core_movement[3]
|
||||
worldMovement.y = core_movement[2]
|
||||
worldMovement.z = dz * core_movement[1] + dx * core_movement[3]
|
||||
core_actualDistance = math.ceil(math.sqrt(worldMovement.x * worldMovement.x + worldMovement.y * worldMovement.y + worldMovement.z * worldMovement.z))
|
||||
core_jumpCost = ship.getEnergyRequired(core_actualDistance)
|
||||
res.x = res.x + worldMovement.x
|
||||
res.y = res.y + worldMovement.y
|
||||
res.z = res.z + worldMovement.z
|
||||
return res
|
||||
end
|
||||
|
||||
function core_warp()
|
||||
-- rs.setOutput(alarm_side, true)
|
||||
if readConfirmation() then
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
ship.movement(core_movement[1], core_movement[2], core_movement[3])
|
||||
ship.rotationSteps(core_rotationSteps)
|
||||
ship.mode(1)
|
||||
ship.jump()
|
||||
-- ship = nil
|
||||
end
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
end
|
||||
|
||||
function core_page_setMovement()
|
||||
ShowTitle("<==== Set movement ====>")
|
||||
SetCursorPos(1, 20)
|
||||
SetColorTitle()
|
||||
ShowMenu("Enter 0 to keep position on that axis")
|
||||
ShowMenu("Use - or n keys to move in opposite direction")
|
||||
ShowMenu("Press Enter to confirm")
|
||||
SetColorDefault()
|
||||
SetCursorPos(1, 3)
|
||||
|
||||
core_movement[1] = core_page_setDistanceAxis(2, "Forward" , "Front", "Back", core_movement[1], math.abs(core_front + core_back + 1))
|
||||
core_movement[2] = core_page_setDistanceAxis(4, "Vertical", "Up" , "Down", core_movement[2], math.abs(core_up + core_down + 1))
|
||||
core_movement[3] = core_page_setDistanceAxis(6, "Lateral" , "Right", "Left", core_movement[3], math.abs(core_left + core_right + 1))
|
||||
core_movement = { ship.movement(core_movement[1], core_movement[2], core_movement[3]) }
|
||||
end
|
||||
|
||||
function core_page_setDistanceAxis(line, axis, positive, negative, userEntry, shipLength)
|
||||
local maximumDistance = shipLength + ship.getMaxJumpDistance()
|
||||
SetColorDisabled()
|
||||
SetCursorPos(3, line + 1)
|
||||
Write(positive .. " is " .. ( shipLength + 1) .. ", maximum is " .. maximumDistance .. " ")
|
||||
SetCursorPos(3, line + 2)
|
||||
Write(negative .. " is " .. (-shipLength - 1) .. ", maximum is " .. -maximumDistance .. " ")
|
||||
|
||||
SetColorDefault()
|
||||
repeat
|
||||
SetCursorPos(1, line)
|
||||
Write(axis .. " movement: ")
|
||||
userEntry = readInputNumber(userEntry)
|
||||
if userEntry ~= 0 and (math.abs(userEntry) <= shipLength or math.abs(userEntry) > maximumDistance) then
|
||||
ShowWarning("Wrong distance. Try again.")
|
||||
end
|
||||
until userEntry == 0 or (math.abs(userEntry) > shipLength and math.abs(userEntry) <= maximumDistance)
|
||||
SetCursorPos(1, line + 1)
|
||||
ClearLine()
|
||||
SetCursorPos(1, line + 2)
|
||||
ClearLine()
|
||||
|
||||
return userEntry
|
||||
end
|
||||
|
||||
function core_page_setRotation()
|
||||
local inputAbort = false
|
||||
local drun = true
|
||||
repeat
|
||||
ShowTitle("<==== Set rotation ====>")
|
||||
core_writeRotation()
|
||||
SetCursorPos(1, 21)
|
||||
SetColorTitle()
|
||||
ShowMenu("Use directional keys")
|
||||
ShowMenu("Press Enter to confirm")
|
||||
SetColorDefault()
|
||||
local params = { event.pull() }
|
||||
local eventName = params[1]
|
||||
local address = params[2]
|
||||
if address == nil then address = "none" end
|
||||
if eventName == "key_down" then
|
||||
local char = params[3]
|
||||
local keycode = params[4]
|
||||
if keycode == 200 then
|
||||
core_rotationSteps = 0
|
||||
elseif keycode == 203 then
|
||||
core_rotationSteps = 3
|
||||
elseif keycode == 205 then
|
||||
core_rotationSteps = 1
|
||||
elseif keycode == 208 then
|
||||
core_rotationSteps = 2
|
||||
elseif keycode == 28 then
|
||||
inputAbort = true
|
||||
else
|
||||
ShowWarning("Key " .. char .. " " .. keycode .. " is invalid")
|
||||
end
|
||||
elseif eventName == "interrupted" then
|
||||
inputAbort = true
|
||||
elseif not common_event(eventName, params[3]) then
|
||||
ShowWarning("Event '" .. eventName .. "', " .. address .. " is unsupported")
|
||||
end
|
||||
until inputAbort
|
||||
core_rotationSteps = ship.rotationSteps(core_rotationSteps)
|
||||
end
|
||||
|
||||
function core_page_setDimensions()
|
||||
ShowTitle("<==== Set dimensions ====>")
|
||||
Write(" Front (".. core_front ..") : ")
|
||||
core_front = readInputNumber(core_front)
|
||||
Write(" Right (".. core_right ..") : ")
|
||||
core_right = readInputNumber(core_right)
|
||||
Write(" Up (".. core_up ..") : ")
|
||||
core_up = readInputNumber(core_up)
|
||||
Write(" Back (".. core_back ..") : ")
|
||||
core_back = readInputNumber(core_back)
|
||||
Write(" Left (".. core_left ..") : ")
|
||||
core_left = readInputNumber(core_left)
|
||||
Write(" Down (".. core_down ..") : ")
|
||||
core_down = readInputNumber(core_down)
|
||||
Write("Setting dimensions...")
|
||||
core_front, core_right, core_up = ship.dim_positive(core_front, core_right, core_up)
|
||||
core_back, core_left, core_down = ship.dim_negative(core_back, core_left, core_down)
|
||||
core_shipSize = ship.getShipSize()
|
||||
if core_shipSize == nil then core_shipSize = 0 end
|
||||
end
|
||||
|
||||
function core_page_summon()
|
||||
ShowTitle("<==== Summon players ====>")
|
||||
local playersString, playersArray = ship.getAttachedPlayers()
|
||||
if #playersArray == 0 then
|
||||
WriteLn("~ no players registered ~")
|
||||
WriteLn("")
|
||||
SetColorTitle()
|
||||
ShowMenu("Press enter to exit")
|
||||
SetColorDefault()
|
||||
readInputNumber("")
|
||||
return
|
||||
end
|
||||
|
||||
for i = 1, #playersArray do
|
||||
WriteLn(i .. ". " .. playersArray[i])
|
||||
end
|
||||
SetColorTitle()
|
||||
ShowMenu("Enter player number")
|
||||
ShowMenu("or press enter to summon everyone")
|
||||
SetColorDefault()
|
||||
|
||||
Write(":")
|
||||
local input = readInputNumber("")
|
||||
if input == "" then
|
||||
ship.summon_all()
|
||||
else
|
||||
input = tonumber(input)
|
||||
ship.summon(input - 1)
|
||||
end
|
||||
end
|
||||
|
||||
function core_page_jumpToBeacon()
|
||||
ShowTitle("<==== Jump to beacon ====>")
|
||||
|
||||
Write("Enter beacon frequency: ")
|
||||
local freq = readInputText("")
|
||||
-- rs.setOutput(alarm_side, true)
|
||||
if readConfirmation() then
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
ship.mode(4)
|
||||
ship.beaconFrequency(freq)
|
||||
ship.jump()
|
||||
-- ship = nil
|
||||
end
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
end
|
||||
|
||||
function core_page_jumpToGate()
|
||||
ShowTitle("<==== Jump to Jumpgate ====>")
|
||||
|
||||
Write("Enter jumpgate name: ")
|
||||
local name = readInputText("")
|
||||
-- rs.setOutput(alarm_side, true)
|
||||
if readConfirmation() then
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
ship.mode(6)
|
||||
ship.targetJumpgate(name)
|
||||
ship.jump()
|
||||
-- ship = nil
|
||||
end
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
end
|
||||
|
||||
function core_page()
|
||||
ShowTitle(label .. " - Ship status")
|
||||
if ship ~= nil then
|
||||
WriteLn("")
|
||||
X, Y, Z = ship.position()
|
||||
WriteLn("Core:")
|
||||
WriteLn(" x, y, z = " .. X .. ", " .. Y .. ", " .. Z)
|
||||
local energy, energyMax = ship.energy()
|
||||
if energy == nil then energy = 0 end
|
||||
if energyMax == nil then energyMax = 1 end
|
||||
WriteLn(" Energy = " .. math.floor(energy / energyMax * 100) .. " % (" .. energy .. "EU)")
|
||||
local playersString, playersArray = ship.getAttachedPlayers()
|
||||
if playersString == "" then players = "-" end
|
||||
WriteLn(" Attached players = " .. playersString)
|
||||
WriteLn("")
|
||||
WriteLn("Dimensions:")
|
||||
WriteLn(" Front, Right, Up = " .. FormatInteger(core_front) .. ", " .. FormatInteger(core_right) .. ", " .. FormatInteger(core_up))
|
||||
WriteLn(" Back, Left, Down = " .. FormatInteger(core_back) .. ", " .. FormatInteger(core_left) .. ", " .. FormatInteger(core_down))
|
||||
WriteLn(" Size = " .. core_shipSize .. " blocks")
|
||||
WriteLn("")
|
||||
WriteLn("Warp data:")
|
||||
core_writeMovement()
|
||||
local dest = core_computeNewCoordinates(X, Y, Z)
|
||||
WriteLn(" Distance = " .. core_actualDistance .. " (" .. core_jumpCost .. "EU, " .. math.floor(energy / core_jumpCost) .. " jumps)")
|
||||
WriteLn(" Dest.coordinates = " .. FormatInteger(dest.x) .. ", " .. FormatInteger(dest.y) .. ", " .. FormatInteger(dest.z))
|
||||
if data.core_summon then
|
||||
WriteLn(" Summon after = Yes")
|
||||
else
|
||||
WriteLn(" Summon after = No")
|
||||
end
|
||||
else
|
||||
ShowWarning("No ship controller detected")
|
||||
end
|
||||
|
||||
SetCursorPos(1, 20)
|
||||
SetColorTitle()
|
||||
ShowMenu("D - Dimensions, N - set ship Name, M - set Movement")
|
||||
ShowMenu("J - Jump, G - jump through Gate, B - jump to Beacon")
|
||||
ShowMenu("H - Hyperspace, C - summon Crew, T - Toggle summon")
|
||||
end
|
||||
|
||||
function core_key(char, keycode)
|
||||
if char == 77 or char == 109 then -- M
|
||||
core_page_setMovement()
|
||||
core_page_setRotation()
|
||||
return true
|
||||
elseif char == 84 or char == 116 then -- T
|
||||
if data.core_summon then
|
||||
data.core_summon = false
|
||||
else
|
||||
data.core_summon = true
|
||||
end
|
||||
data_save()
|
||||
return true
|
||||
elseif char == 68 or char == 100 then -- D
|
||||
core_page_setDimensions()
|
||||
return true
|
||||
elseif char == 74 or char == 106 then -- J
|
||||
core_warp()
|
||||
return true
|
||||
elseif char == 67 or char == 99 or keycode == 46 then -- C
|
||||
core_page_summon()
|
||||
return true
|
||||
elseif char == 66 or char == 98 then -- B
|
||||
core_page_jumpToBeacon()
|
||||
return true
|
||||
elseif char == 71 or char == 103 then -- G
|
||||
core_page_jumpToGate()
|
||||
return true
|
||||
elseif char == 72 or char == 104 then -- H
|
||||
-- rs.setOutput(alarm_side, true)
|
||||
if readConfirmation() then
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
ship.mode(5)
|
||||
ship.jump()
|
||||
-- ship = nil
|
||||
end
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
return true
|
||||
elseif char == 78 or char == 110 then -- N
|
||||
data_setName()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
----------- Boot sequence
|
||||
|
||||
label = computer.address()
|
||||
if not label then
|
||||
label = "" .. computer.address()
|
||||
end
|
||||
|
||||
-- read configuration
|
||||
data_read()
|
||||
|
||||
-- initial scanning
|
||||
ShowTitle(label .. " - Connecting...")
|
||||
WriteLn("")
|
||||
|
||||
-- clear previous events
|
||||
repeat
|
||||
until event.pull(0) == nil
|
||||
|
||||
ship = nil
|
||||
for address, componentType in component.list() do
|
||||
os.sleep(0)
|
||||
Write("Checking " .. componentType .. " ")
|
||||
if componentType == "warpdriveShipController" then
|
||||
Write("wrapping!")
|
||||
ship = component.proxy(address)
|
||||
end
|
||||
WriteLn("")
|
||||
end
|
||||
|
||||
if not computer.address() and ship ~= nil then
|
||||
data_setName()
|
||||
end
|
||||
|
||||
-- peripherals status
|
||||
function connections_page()
|
||||
ShowTitle(label .. " - Connections")
|
||||
|
||||
WriteLn("")
|
||||
if ship == nil then
|
||||
SetColorDisabled()
|
||||
WriteLn("No ship controller detected")
|
||||
else
|
||||
SetColorSuccess()
|
||||
WriteLn("Ship controller detected")
|
||||
end
|
||||
|
||||
WriteLn("")
|
||||
SetColorTitle()
|
||||
WriteLn("Please refer to below menu for keyboard controls")
|
||||
WriteLn("For example, press 1 to access Ship core page")
|
||||
end
|
||||
|
||||
-- peripheral boot up
|
||||
Clear()
|
||||
connections_page()
|
||||
SetColorDefault()
|
||||
WriteLn("")
|
||||
os.sleep(0)
|
||||
core_boot()
|
||||
os.sleep(0)
|
||||
|
||||
-- main loop
|
||||
abort = false
|
||||
refresh = true
|
||||
page = connections_page
|
||||
keyHandler = nil
|
||||
repeat
|
||||
ClearWarning()
|
||||
if refresh then
|
||||
Clear()
|
||||
page()
|
||||
menu_common()
|
||||
refresh = false
|
||||
end
|
||||
params = { event.pull() }
|
||||
eventName = params[1]
|
||||
address = params[2]
|
||||
if address == nil then address = "none" end
|
||||
-- WriteLn("...")
|
||||
-- WriteLn("Event '" .. eventName .. "', " .. address .. ", " .. params[3] .. " received")
|
||||
-- os.sleep(0.2)
|
||||
if eventName == "key_down" then
|
||||
char = params[3]
|
||||
keycode = params[4]
|
||||
if char == 88 or char == 120 or keycode == 45 then -- x for eXit
|
||||
abort = true
|
||||
elseif char == 48 or keycode == 11 or keycode == 82 then -- 0
|
||||
page = connections_page
|
||||
keyHandler = nil
|
||||
refresh = true
|
||||
elseif char == 49 or keycode == 2 or keycode == 79 then -- 1
|
||||
page = core_page
|
||||
keyHandler = core_key
|
||||
refresh = true
|
||||
elseif keyHandler ~= nil and keyHandler(char, keycode) then
|
||||
refresh = true
|
||||
os.sleep(0)
|
||||
elseif char == 0 then -- control chars
|
||||
refresh = false
|
||||
os.sleep(0)
|
||||
else
|
||||
ShowWarning("Key " .. char .. " " .. keycode .. " is invalid")
|
||||
os.sleep(0.2)
|
||||
end
|
||||
elseif eventName == "interrupted" then
|
||||
abort = true
|
||||
elseif not common_event(eventName, params[3]) then
|
||||
ShowWarning("Event '" .. eventName .. "', " .. address .. " is unsupported")
|
||||
refresh = true
|
||||
os.sleep(0.2)
|
||||
end
|
||||
until abort
|
||||
|
||||
-- exiting
|
||||
if data.core_summon then
|
||||
data.core_summon = false
|
||||
data_save()
|
||||
end
|
||||
|
||||
if ship ~= nil then
|
||||
ship.mode(0)
|
||||
end
|
||||
|
||||
-- clear screens on exit
|
||||
SetMonitorColorFrontBack(0xFFFFFF, 0x000000)
|
||||
term.clear()
|
||||
SetCursorPos(1, 1)
|
||||
WriteLn("Program terminated")
|
||||
WriteLn("Type reboot to restart it")
|
|
@ -0,0 +1,680 @@
|
|||
|
||||
package.loaded.warpdriveCommons = nil
|
||||
local w = require("warpdriveCommons")
|
||||
|
||||
local event = require("event")
|
||||
|
||||
local data
|
||||
|
||||
----------- Ship support
|
||||
|
||||
local ship_x, ship_y, ship_z = 0, 0, 0
|
||||
local ship_front = 0
|
||||
local ship_right = 0
|
||||
local ship_up = 0
|
||||
local ship_back = 0
|
||||
local ship_left = 0
|
||||
local ship_down = 0
|
||||
local ship_isInHyper = false
|
||||
local ship_jumpCost = 0
|
||||
local ship_shipSize = 0
|
||||
local ship_movement = { 0, 0, 0 }
|
||||
local ship_rotationSteps = 0
|
||||
local ship_indexPlayer = 0
|
||||
local ship_indexTarget = 0
|
||||
local ship = nil
|
||||
|
||||
function ship_read(parData)
|
||||
data = parData
|
||||
if data.ship_summon == nil then data.ship_summon = false; end
|
||||
end
|
||||
|
||||
function ship_boot()
|
||||
if ship == nil then
|
||||
return
|
||||
end
|
||||
|
||||
w.setColorNormal()
|
||||
w.writeLn("Booting Ship")
|
||||
|
||||
if data.ship_summon then
|
||||
ship.summon_all()
|
||||
end
|
||||
|
||||
w.write("- internal parameters: ")
|
||||
ship_front, ship_right, ship_up = ship.dim_positive()
|
||||
ship_back, ship_left, ship_down = ship.dim_negative()
|
||||
ship_isInHyper = ship.isInHyperspace()
|
||||
ship_rotationSteps = ship.rotationSteps()
|
||||
ship_movement = { ship.movement() }
|
||||
if ship.direction ~= nil then
|
||||
ship.direction(666)
|
||||
ship.distance(0)
|
||||
end
|
||||
w.setColorSuccess()
|
||||
w.writeLn("ok")
|
||||
|
||||
w.setColorNormal()
|
||||
w.write("- detecting Ship Core: ")
|
||||
local timeout = 10
|
||||
repeat
|
||||
isAttached = ship.isAttached()
|
||||
w.sleep(0.05)
|
||||
timeout = timeout - 1
|
||||
until isAttached ~= false or timeout < 0
|
||||
if timeout < 0 then
|
||||
w.setColorWarning()
|
||||
w.writeLn("failed")
|
||||
w.writeLn("")
|
||||
w.writeLn("Ship Core shall be attached horizontally")
|
||||
w.writeLn("with Ship Controller!")
|
||||
w.setColorNormal()
|
||||
w.sleep(6)
|
||||
w.reboot()
|
||||
else
|
||||
w.setColorSuccess()
|
||||
w.writeLn("linked")
|
||||
end
|
||||
w.sleep(0.2)
|
||||
|
||||
w.setColorNormal()
|
||||
w.write("- global position : ")
|
||||
timeout = 10
|
||||
repeat
|
||||
pos = ship.position()
|
||||
w.sleep(0.05)
|
||||
timeout = timeout - 1
|
||||
until pos ~= nil or timeout < 0
|
||||
ship_x, ship_y, ship_z = ship.position()
|
||||
if timeout < 0 then
|
||||
w.setColorWarning()
|
||||
w.writeLn("failed")
|
||||
w.writeLn("")
|
||||
w.writeLn("Something is wrong here, rebooting...")
|
||||
w.setColorNormal()
|
||||
w.sleep(2)
|
||||
w.reboot()
|
||||
else
|
||||
w.setColorSuccess()
|
||||
w.writeLn("triangulated")
|
||||
end
|
||||
w.sleep(0.2)
|
||||
|
||||
w.setColorNormal()
|
||||
w.write("- integrity check : ")
|
||||
timeout = 10
|
||||
repeat
|
||||
ship_shipSize = ship.getShipSize()
|
||||
w.sleep(0.05)
|
||||
timeout = timeout - 1
|
||||
until ship_shipSize ~= nil or timeout < 0
|
||||
if timeout < 0 then
|
||||
w.setColorWarning()
|
||||
w.writeLn("failed")
|
||||
w.writeLn("")
|
||||
w.writeLn("Ship is too big? ignoring for now...")
|
||||
w.setColorNormal()
|
||||
w.sleep(1)
|
||||
else
|
||||
w.setColorSuccess()
|
||||
w.writeLn("passed")
|
||||
end
|
||||
|
||||
ship.mode(1)
|
||||
w.sleep(0.3)
|
||||
end
|
||||
|
||||
function ship_writeMovement()
|
||||
local message = " Movement = "
|
||||
local count = 0
|
||||
if ship_movement[1] > 0 then
|
||||
message = message .. ship_movement[1] .. " front"
|
||||
count = count + 1
|
||||
elseif ship_movement[1] < 0 then
|
||||
message = message .. (- ship_movement[1]) .. " back"
|
||||
count = count + 1
|
||||
end
|
||||
if ship_movement[2] > 0 then
|
||||
if count > 0 then message = message .. ", "; end
|
||||
message = message .. ship_movement[2] .. " up"
|
||||
count = count + 1
|
||||
elseif ship_movement[2] < 0 then
|
||||
if count > 0 then message = message .. ", "; end
|
||||
message = message .. (- ship_movement[2]) .. " down"
|
||||
count = count + 1
|
||||
end
|
||||
if ship_movement[3] > 0 then
|
||||
if count > 0 then message = message .. ", "; end
|
||||
message = message .. ship_movement[3] .. " right"
|
||||
count = count + 1
|
||||
elseif ship_movement[3] < 0 then
|
||||
if count > 0 then message = message .. ", "; end
|
||||
message = message .. (- ship_movement[3]) .. " left"
|
||||
count = count + 1
|
||||
end
|
||||
|
||||
if ship_rotationSteps == 1 then
|
||||
if count > 0 then message = message .. ", "; end
|
||||
message = message .. "Turn right"
|
||||
count = count + 1
|
||||
elseif ship_rotationSteps == 2 then
|
||||
if count > 0 then message = message .. ", "; end
|
||||
message = message .. "Turn back"
|
||||
count = count + 1
|
||||
elseif ship_rotationSteps == 3 then
|
||||
if count > 0 then message = message .. ", "; end
|
||||
message = message .. "Turn left"
|
||||
count = count + 1
|
||||
end
|
||||
|
||||
if count == 0 then
|
||||
message = message .. "(none)"
|
||||
end
|
||||
w.writeLn(message)
|
||||
end
|
||||
|
||||
function ship_writeRotation()
|
||||
if ship_rotationSteps == 0 then
|
||||
w.writeLn(" Rotation = Front ")
|
||||
elseif ship_rotationSteps == 1 then
|
||||
w.writeLn(" Rotation = Right +90")
|
||||
elseif ship_rotationSteps == 2 then
|
||||
w.writeLn(" Rotation = Back 180 ")
|
||||
elseif ship_rotationSteps == 3 then
|
||||
w.writeLn(" Rotation = Left -90 ")
|
||||
end
|
||||
end
|
||||
|
||||
function ship_computeNewCoordinates(cx, cy, cz)
|
||||
local res = { x = cx, y = cy, z = cz }
|
||||
local dx, dy, dz = ship.getOrientation()
|
||||
if dx == nil then
|
||||
dx, dy, dz = 0, 0, 0
|
||||
end
|
||||
local worldMovement = { x = 0, y = 0, z = 0 }
|
||||
worldMovement.x = dx * ship_movement[1] - dz * ship_movement[3]
|
||||
worldMovement.y = ship_movement[2]
|
||||
worldMovement.z = dz * ship_movement[1] + dx * ship_movement[3]
|
||||
ship_actualDistance = math.ceil(math.sqrt(worldMovement.x * worldMovement.x + worldMovement.y * worldMovement.y + worldMovement.z * worldMovement.z))
|
||||
ship_jumpCost = ship.getEnergyRequired(ship_actualDistance)
|
||||
res.x = res.x + worldMovement.x
|
||||
res.y = res.y + worldMovement.y
|
||||
res.z = res.z + worldMovement.z
|
||||
return res
|
||||
end
|
||||
|
||||
function ship_warp()
|
||||
-- rs.setOutput(alarm_side, true)
|
||||
if w.input_readConfirmation("Engage jump drive? (Y/n)") then
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
ship.movement(ship_movement[1], ship_movement[2], ship_movement[3])
|
||||
ship.rotationSteps(ship_rotationSteps)
|
||||
ship.mode(1)
|
||||
ship.jump()
|
||||
-- ship = nil
|
||||
end
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
end
|
||||
|
||||
function ship_page_setMovement()
|
||||
w.page_begin("<==== Set ship movement ====>")
|
||||
w.setCursorPos(1, 18)
|
||||
w.setColorControl()
|
||||
w.writeFullLine(" Enter jump distance on each axis (0-9)")
|
||||
w.writeFullLine(" Enter 0 to keep position on that axis")
|
||||
w.writeFullLine(" Use - or n keys to move in opposite direction")
|
||||
w.writeFullLine(" Press Enter to save your selection")
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(1, 3)
|
||||
|
||||
ship_movement[1] = ship_page_setDistanceAxis(3, "Forward" , "Front", "Back", ship_movement[1], math.abs(ship_front + ship_back + 1))
|
||||
ship_movement[2] = ship_page_setDistanceAxis(5, "Vertical", "Up" , "Down", ship_movement[2], math.abs(ship_up + ship_down + 1))
|
||||
ship_movement[3] = ship_page_setDistanceAxis(7, "Lateral" , "Right", "Left", ship_movement[3], math.abs(ship_left + ship_right + 1))
|
||||
ship_movement = { ship.movement(ship_movement[1], ship_movement[2], ship_movement[3]) }
|
||||
end
|
||||
|
||||
function ship_page_setDistanceAxis(line, axis, positive, negative, userEntry, shipLength)
|
||||
local maximumDistance = shipLength + ship.getMaxJumpDistance()
|
||||
w.setColorDisabled()
|
||||
w.setCursorPos(3, line + 1)
|
||||
w.write(positive .. " is " .. ( shipLength + 1) .. " to " .. maximumDistance .. " blocks ")
|
||||
w.setCursorPos(3, line + 2)
|
||||
w.write(negative .. " is " .. (-shipLength - 1) .. " to " .. -maximumDistance .. " blocks ")
|
||||
|
||||
w.setColorNormal()
|
||||
repeat
|
||||
w.setCursorPos(1, line)
|
||||
w.write(axis .. " movement: ")
|
||||
userEntry = w.input_readNumber(userEntry)
|
||||
if userEntry ~= 0 and (math.abs(userEntry) <= shipLength or math.abs(userEntry) > maximumDistance) then
|
||||
w.status_showWarning("Wrong distance. Try again.")
|
||||
end
|
||||
until userEntry == 0 or (math.abs(userEntry) > shipLength and math.abs(userEntry) <= maximumDistance)
|
||||
w.setCursorPos(1, line + 1)
|
||||
w.clearLine()
|
||||
w.setCursorPos(1, line + 2)
|
||||
w.clearLine()
|
||||
|
||||
return userEntry
|
||||
end
|
||||
|
||||
function ship_page_setRotation()
|
||||
local inputAbort = false
|
||||
local drun = true
|
||||
w.page_begin("<==== Set ship rotation ====>")
|
||||
w.setCursorPos(1, 19)
|
||||
w.setColorControl()
|
||||
w.writeFullLine(" Select ship rotation (Up, Down, Left, Right)")
|
||||
w.writeFullLine(" Select Front to keep current orientation")
|
||||
w.writeFullLine(" Press Enter to save your selection")
|
||||
repeat
|
||||
w.setCursorPos(1, 3)
|
||||
w.setColorNormal()
|
||||
ship_writeRotation()
|
||||
local params = { event.pull() }
|
||||
local eventName = params[1]
|
||||
local address = params[2]
|
||||
if address == nil then address = "none" end
|
||||
local firstParam = params[3]
|
||||
if firstParam == nil then firstParam = "none" end
|
||||
if eventName == "key_down" then
|
||||
local character = string.char(params[3])
|
||||
local keycode = params[4]
|
||||
|
||||
if keycode == 200 then
|
||||
ship_rotationSteps = 0
|
||||
elseif keycode == 203 then
|
||||
ship_rotationSteps = 3
|
||||
elseif keycode == 205 then
|
||||
ship_rotationSteps = 1
|
||||
elseif keycode == 208 then
|
||||
ship_rotationSteps = 2
|
||||
elseif keycode == 28 then
|
||||
inputAbort = true
|
||||
else
|
||||
w.status_showWarning("Key " .. keycode .. " is invalid")
|
||||
end
|
||||
elseif eventName == "interrupted" then
|
||||
inputAbort = true
|
||||
elseif not w.event_handler(eventName, params[2]) then
|
||||
w.status_showWarning("Event '" .. eventName .. "', " .. address .. " is unsupported")
|
||||
end
|
||||
until inputAbort
|
||||
ship_rotationSteps = ship.rotationSteps(ship_rotationSteps)
|
||||
end
|
||||
|
||||
function ship_page_setDimensions()
|
||||
w.page_begin("<==== Set ship dimensions ====>")
|
||||
w.setCursorPos(1, 18)
|
||||
w.setColorControl()
|
||||
w.writeFullLine(" Enter ship size in blocks (0-9)")
|
||||
w.writeFullLine(" First block next to Ship counts as 1")
|
||||
w.writeFullLine(" Ship controller counts as 'Front = 1'")
|
||||
w.writeFullLine(" Press Enter to save your selection")
|
||||
|
||||
w.setCursorPos(1, 3)
|
||||
w.setColorNormal()
|
||||
w.write(" Front (".. ship_front ..") : ")
|
||||
ship_front = w.input_readNumber(ship_front)
|
||||
w.write(" Right (".. ship_right ..") : ")
|
||||
ship_right = w.input_readNumber(ship_right)
|
||||
w.write(" Up (".. ship_up ..") : ")
|
||||
ship_up = w.input_readNumber(ship_up)
|
||||
w.write(" Back (".. ship_back ..") : ")
|
||||
ship_back = w.input_readNumber(ship_back)
|
||||
w.write(" Left (".. ship_left ..") : ")
|
||||
ship_left = w.input_readNumber(ship_left)
|
||||
w.write(" Down (".. ship_down ..") : ")
|
||||
ship_down = w.input_readNumber(ship_down)
|
||||
w.write("Setting dimensions...")
|
||||
ship_front, ship_right, ship_up = ship.dim_positive(ship_front, ship_right, ship_up)
|
||||
ship_back, ship_left, ship_down = ship.dim_negative(ship_back, ship_left, ship_down)
|
||||
ship_shipSize = ship.getShipSize()
|
||||
if ship_shipSize == nil then ship_shipSize = 0 end
|
||||
end
|
||||
|
||||
function ship_page_summon() -- no longer used
|
||||
w.page_begin("<==== Summon players ====>")
|
||||
local stringPlayers, arrayPlayers = ship.getAttachedPlayers()
|
||||
if stringPlayers == nil or #arrayPlayers == 0 then
|
||||
w.writeLn("~ no players registered ~")
|
||||
w.writeLn("")
|
||||
w.setColorControl()
|
||||
w.writeFullLine("Press enter to exit")
|
||||
w.setColorNormal()
|
||||
w.input_readNumber("")
|
||||
return
|
||||
end
|
||||
for i = 1, #arrayPlayers do
|
||||
w.writeLn(i .. ". " .. arrayPlayers[i])
|
||||
end
|
||||
w.setColorControl()
|
||||
w.writeFullLine("Enter player number")
|
||||
w.writeFullLine("or press enter to summon everyone")
|
||||
w.setColorNormal()
|
||||
|
||||
w.write(":")
|
||||
local input = w.input_readNumber("")
|
||||
if input == "" then
|
||||
ship.summon_all()
|
||||
else
|
||||
input = tonumber(input)
|
||||
ship.summon(input - 1)
|
||||
end
|
||||
end
|
||||
|
||||
function ship_page_jumpToBeacon()
|
||||
w.page_begin("<==== Jump to beacon ====>")
|
||||
|
||||
w.write("Enter beacon frequency: ")
|
||||
local freq = w.input_readText("")
|
||||
-- rs.setOutput(alarm_side, true)
|
||||
if w.input_readConfirmation() then
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
ship.mode(4)
|
||||
ship.beaconFrequency(freq)
|
||||
ship.jump()
|
||||
-- ship = nil
|
||||
end
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
end
|
||||
|
||||
function ship_page_jumpToGate()
|
||||
w.page_begin("<==== Jump through Jumpgate ====>")
|
||||
w.writeLn("")
|
||||
w.writeLn("Your ship should be already inside a jumpgate")
|
||||
|
||||
w.setCursorPos(1, 20)
|
||||
w.setColorControl()
|
||||
w.writeFullLine("Enter target jumpgate name (a-z, 0-9)")
|
||||
w.writeFullLine("Press enter to save jumpgate name")
|
||||
|
||||
w.setCursorPos(1, 5)
|
||||
w.setColorNormal()
|
||||
w.write("Target jumpgate name: ")
|
||||
local name = w.input_readText("")
|
||||
-- rs.setOutput(alarm_side, true)
|
||||
if w.input_readConfirmation("Engage gate jumping? (Y/n)") then
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
ship.mode(6)
|
||||
ship.targetJumpgate(name)
|
||||
ship.jump()
|
||||
-- ship = nil
|
||||
end
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
end
|
||||
|
||||
function ship_page_controls()
|
||||
w.page_begin(w.data_getName() .. " - Ship controls")
|
||||
if ship == nil then
|
||||
w.status_showWarning("No ship controller detected")
|
||||
elseif ship.isAttached() ~= true then
|
||||
w.status_showWarning("No ship core detected")
|
||||
else
|
||||
-- w.writeLn("")
|
||||
ship_x, ship_y, ship_z = ship.position()
|
||||
if ship_x == nil then
|
||||
ship_x, ship_y, ship_z = 0, 0, 0
|
||||
end
|
||||
w.writeLn("Ship:")
|
||||
w.writeLn(" Current position = " .. ship_x .. ", " .. ship_y .. ", " .. ship_z)
|
||||
local energy, energyMax = ship.energy()
|
||||
if energy == nil then energy = 0 end
|
||||
if energyMax == nil or energyMax == 0 then energyMax = 1 end
|
||||
w.writeLn(" Energy = " .. math.floor(energy / energyMax * 100) .. " % (" .. energy .. " EU)")
|
||||
|
||||
w.writeLn("")
|
||||
-- w.writeLn("")
|
||||
w.writeLn("Dimensions:")
|
||||
w.writeLn(" Front, Right, Up = " .. w.format_integer(ship_front) .. ", " .. w.format_integer(ship_right) .. ", " .. w.format_integer(ship_up) .. " blocks")
|
||||
w.writeLn(" Back, Left, Down = " .. w.format_integer(ship_back) .. ", " .. w.format_integer(ship_left) .. ", " .. w.format_integer(ship_down) .. " blocks")
|
||||
w.writeLn(" Size = " .. ship_shipSize .. " blocks")
|
||||
w.writeLn("")
|
||||
w.writeLn("Warp data:")
|
||||
ship_writeMovement()
|
||||
local dest = ship_computeNewCoordinates(ship_x, ship_y, ship_z)
|
||||
w.writeLn(" Distance = " .. ship_actualDistance .. " (" .. ship_jumpCost .. " EU, " .. math.floor(energy / ship_jumpCost) .. " jumps)")
|
||||
w.writeLn(" Target position = " .. w.format_integer(dest.x) .. ", " .. w.format_integer(dest.y) .. ", " .. w.format_integer(dest.z))
|
||||
end
|
||||
|
||||
w.setCursorPos(1, 20)
|
||||
w.setColorControl()
|
||||
w.writeFullLine(" set ship Name (N), Dimensions (D), Movement (M)")
|
||||
if ship_isInHyper then
|
||||
w.writeFullLine(" Jump to move ship (M/J), exit Hyperspace (H)")
|
||||
else
|
||||
w.writeFullLine(" Jump to move ship (M/J), enter Hyperspace (H)")
|
||||
end
|
||||
end
|
||||
|
||||
function ship_key_controls(character, keycode)
|
||||
if character == 'm' or character == 'M' then -- M
|
||||
ship_page_setMovement()
|
||||
ship_page_setRotation()
|
||||
ship_warp()
|
||||
return true
|
||||
elseif character == 'd' or character == 'D' then -- D
|
||||
ship_page_setDimensions()
|
||||
return true
|
||||
elseif character == 'j' or character == 'J' then -- J
|
||||
ship_warp()
|
||||
return true
|
||||
elseif character == 'h' or character == 'H' then -- H
|
||||
-- rs.setOutput(alarm_side, true)
|
||||
if w.input_readConfirmation("Engage hyperdrive? (Y/n)") then
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
ship.mode(5)
|
||||
ship.jump()
|
||||
-- ship = nil
|
||||
end
|
||||
-- rs.setOutput(alarm_side, false)
|
||||
return true
|
||||
elseif character == 'n' or character == 'N' then
|
||||
w.data_setName()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function ship_writeArray(arrayValues, indexSelected)
|
||||
if indexSelected then
|
||||
indexSelected = (indexSelected + #arrayValues) % #arrayValues
|
||||
end
|
||||
|
||||
local indexSplit = math.ceil(#arrayValues / 2)
|
||||
for i = 1, indexSplit do
|
||||
if indexSelected and i == indexSelected + 1 then
|
||||
w.setColorSelected()
|
||||
w.write(">" .. string.sub(arrayValues[i] .. " ", 1, 24))
|
||||
w.setColorNormal()
|
||||
else
|
||||
w.write(" " .. string.sub(arrayValues[i] .. " ", 1, 24))
|
||||
end
|
||||
if arrayValues[i + indexSplit] ~= nil then
|
||||
if indexSelected and i + indexSplit == indexSelected + 1 then
|
||||
w.setColorSelected()
|
||||
w.writeLn(">" .. string.sub(arrayValues[i + indexSplit] .. " ", 1, 24))
|
||||
w.setColorNormal()
|
||||
else
|
||||
w.writeLn(" " .. arrayValues[i + indexSplit])
|
||||
end
|
||||
else
|
||||
w.writeLn("")
|
||||
end
|
||||
end
|
||||
return indexSelected
|
||||
end
|
||||
|
||||
function ship_page_crew()
|
||||
w.page_begin(w.data_getName() .. " - Ship crew")
|
||||
if ship == nil then
|
||||
w.status_showWarning("No ship controller detected")
|
||||
elseif ship.isAttached() ~= true then
|
||||
w.status_showWarning("No ship core detected")
|
||||
else
|
||||
w.writeLn("Attached players:")
|
||||
local stringPlayers, _ = ship.getAttachedPlayers()
|
||||
if stringPlayers == nil or stringPlayers == "" then
|
||||
stringPlayers = "~ no registered player ~"
|
||||
end
|
||||
local arrayPlayers = w.data_splitString(stringPlayers, ",")
|
||||
ship_indexPlayer = ship_writeArray(arrayPlayers, ship_indexPlayer)
|
||||
w.writeLn("")
|
||||
w.writeLn("Summon crew after short jump = " .. w.format_boolean(data.ship_summon, "YES", "no"))
|
||||
-- w.writeLn("")
|
||||
-- w.writeLn("Beacon jump: -admin only-")
|
||||
end
|
||||
|
||||
w.setCursorPos(1, 20)
|
||||
w.setColorControl()
|
||||
w.writeFullLine(" Summon all crew (S), Toggle summon after jump (T)")
|
||||
w.writeFullLine(" select crew (arrows), summon selected crew (enter)")
|
||||
end
|
||||
|
||||
function ship_key_crew(character, keycode)
|
||||
if character == 't' or character == 'T' then -- T
|
||||
if data.ship_summon then
|
||||
data.ship_summon = false
|
||||
else
|
||||
data.ship_summon = true
|
||||
end
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 's' or character == 'S' then -- S
|
||||
ship.summon_all()
|
||||
return true
|
||||
elseif keycode == 28 then -- Enter
|
||||
local success, namePlayer = ship.summon(ship_indexPlayer)
|
||||
if success then
|
||||
w.status_showSuccess("Engaging teleportation for " .. namePlayer .. "...")
|
||||
else
|
||||
w.status_showWarning("Failed to summon crew member")
|
||||
end
|
||||
return true
|
||||
elseif character == 'g' or character == 'G' then -- G
|
||||
ship_page_jumpToGate()
|
||||
return true
|
||||
elseif keycode == 200 or keycode == 203 or character == '-' then -- Up or Left or -
|
||||
ship_indexPlayer = ship_indexPlayer - 1
|
||||
return true
|
||||
elseif keycode == 208 or keycode == 205 or character == '+' then -- Down or Right or +
|
||||
ship_indexPlayer = ship_indexPlayer + 1
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function ship_page_navigation()
|
||||
w.page_begin(w.data_getName() .. " - Ship navigation")
|
||||
if ship == nil then
|
||||
w.status_showWarning("No ship controller detected")
|
||||
elseif ship.isAttached() ~= true then
|
||||
w.status_showWarning("No ship core detected")
|
||||
else
|
||||
local locationCurrent = "somewhere..." -- @TODO ship.getLocation()
|
||||
w.writeLn("Current ship location : " .. locationCurrent)
|
||||
w.writeLn("Jumpgates or beacons in range:")
|
||||
local stringTargets, _ = "not implemented" -- ship.getTargets()
|
||||
if stringTargets == nil or stringTargets == "" then
|
||||
stringTargets = "~ no beacon nor jumpgate in range ~"
|
||||
end
|
||||
local arrayTargets = w.data_splitString(stringTargets, ",")
|
||||
ship_indexTarget = ship_writeArray(arrayTargets, ship_indexTarget)
|
||||
-- w.writeLn("")
|
||||
-- w.writeLn("Beacon jump: -admin only-")
|
||||
end
|
||||
|
||||
w.setCursorPos(1, 20)
|
||||
w.setColorControl()
|
||||
w.writeFullLine(" select target (arrows), register target (enter)")
|
||||
w.writeFullLine(" jump through Gate (G)")
|
||||
end
|
||||
|
||||
function ship_key_navigation(character, keycode)
|
||||
if keycode == 28 then -- Enter
|
||||
-- local success, xxx = ship.xxx(ship_indexTarget)
|
||||
-- if success then
|
||||
-- w.status_showSuccess("Engaging jumpgate jump to " .. xxx .. "...")
|
||||
-- else
|
||||
-- w.status_showWarning("Failed to summon crew member")
|
||||
-- end
|
||||
return true
|
||||
-- elseif character == 'b' or character == 'B' then -- B
|
||||
-- ship_page_jumpToBeacon()
|
||||
-- return true
|
||||
elseif character == 'g' or character == 'G' then -- G
|
||||
ship_page_jumpToGate()
|
||||
return true
|
||||
elseif keycode == 200 or keycode == 203 or character == '-' then -- Up or Left or -
|
||||
ship_indexTarget = ship_indexTarget - 1
|
||||
return true
|
||||
elseif keycode == 208 or keycode == 205 or character == '+' then -- Down or Right or +
|
||||
ship_indexTarget = ship_indexTarget + 1
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function ship_register()
|
||||
w.device_register("warpdriveShipController",
|
||||
function(deviceType, address, wrap) ship = wrap end,
|
||||
function() end)
|
||||
w.event_register("shipCoreCooldownDone" , function() w.status_showWarning("Ship core cooldown done") return false end )
|
||||
w.data_register("ship", ship_read, nil)
|
||||
end
|
||||
|
||||
----------- connections status
|
||||
|
||||
function connections_page(isBooting)
|
||||
w.page_begin(w.data_getName() .. " - Connections")
|
||||
|
||||
w.writeLn("")
|
||||
|
||||
if ship == nil then
|
||||
w.setColorDisabled()
|
||||
w.writeLn("No ship controller detected")
|
||||
else
|
||||
w.setColorSuccess()
|
||||
w.writeLn("Ship controller detected")
|
||||
if isBooting then
|
||||
ship_boot()
|
||||
end
|
||||
end
|
||||
|
||||
w.writeLn("")
|
||||
w.setColorNormal()
|
||||
w.writeLn("This is a keyboard controlled user interface.")
|
||||
w.write("Key controls are written like so: ")
|
||||
w.setColorControl()
|
||||
w.write("Action (key)")
|
||||
w.setColorNormal()
|
||||
w.writeLn(".")
|
||||
w.write("For example, typing ")
|
||||
w.setColorControl()
|
||||
w.write(" 1 ")
|
||||
w.setColorNormal()
|
||||
w.writeLn(" will open Ship controls.")
|
||||
end
|
||||
|
||||
----------- Boot sequence
|
||||
|
||||
w.page_setEndText(" Home (0), Controls (1), Crew (2), Navigation (3)")
|
||||
w.page_register('0', connections_page, nil)
|
||||
w.page_register('1', ship_page_controls, ship_key_controls)
|
||||
w.page_register('2', ship_page_crew, ship_key_crew)
|
||||
w.page_register('3', ship_page_navigation, ship_key_navigation)
|
||||
ship_register()
|
||||
|
||||
w.boot()
|
||||
w.run()
|
||||
|
||||
if data.ship_summon then
|
||||
data.ship_summon = false
|
||||
w.data_save()
|
||||
end
|
||||
|
||||
if ship ~= nil then
|
||||
ship.mode(0)
|
||||
end
|
||||
|
||||
w.close()
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,887 @@
|
|||
|
||||
package.loaded.warpdriveCommons = nil
|
||||
local w = require("warpdriveCommons")
|
||||
|
||||
local data
|
||||
|
||||
----------- Attack lasers support
|
||||
|
||||
local laser_batteryIndex = 1
|
||||
local laser_batteries = {}
|
||||
local laser_stationIndex = 1
|
||||
local laser_stations = {}
|
||||
local laserAddresses = {}
|
||||
local lasercamAddresses = {}
|
||||
|
||||
function laser_save(parData)
|
||||
-- rebuild a clean structure, skipping the device objects
|
||||
data.laser_batteries = {}
|
||||
for keyBattery, laserbattery in pairs(laser_batteries) do
|
||||
data.laser_batteries[keyBattery] = {
|
||||
name = laserbattery.name,
|
||||
frequency = laserbattery.frequency,
|
||||
headAddress = laserbattery.headAddress,
|
||||
boosterAddresses = laserbattery.boosterAddresses }
|
||||
end
|
||||
data.laser_stations = {}
|
||||
for keyStation, laserstation in pairs(laser_stations) do
|
||||
data.laser_stations[keyStation] = {
|
||||
name = laserstation.name,
|
||||
cameraAddress = laserstation.cameraAddress,
|
||||
batteries = {}}
|
||||
for keyBattery, laserbattery in pairs(laser_stations[keyStation].batteries) do
|
||||
data.laser_stations[keyStation].batteries[keyBattery] = {
|
||||
name = laserbattery.name,
|
||||
enabled = laserbattery.enabled }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function laser_read(parData)
|
||||
data = parData
|
||||
if data.laser_batteries == nil then data.laser_batteries = {}; end
|
||||
laser_batteries = data.laser_batteries
|
||||
for keyBattery, laserbattery in pairs(laser_batteries) do
|
||||
if laserbattery.headAddress ~= nil then
|
||||
laserbattery.head = w.device_get(laserbattery.headAddress)
|
||||
end
|
||||
if laserbattery.name == nil then
|
||||
laserbattery.name = "noname"
|
||||
end
|
||||
if laserbattery.boosterAddresses == nil then
|
||||
laserbattery.boosterAddresses = {}
|
||||
end
|
||||
laserbattery.boosters = {}
|
||||
for boosterKey, boosterAddress in pairs(laserbattery.boosterAddresses) do
|
||||
laserbattery.boosters[boosterKey] = w.device_get(boosterAddress)
|
||||
end
|
||||
end
|
||||
if data.laser_stations == nil then data.laser_stations = {}; end
|
||||
laser_stations = data.laser_stations
|
||||
for keyStation, laserstation in pairs(laser_stations) do
|
||||
if laserstation.cameraAddress ~= nil then
|
||||
laserstation.camera = w.device_get(laserstation.cameraAddress)
|
||||
end
|
||||
if laserstation.name == nil then
|
||||
laserstation.name = "noname"
|
||||
end
|
||||
if laserstation.batteries == nil then
|
||||
laserstation.batteries = {}
|
||||
end
|
||||
end
|
||||
if data.laser_firingMode == nil then data.laser_firingMode = "boosted"; end
|
||||
if data.laser_firingScatter == nil then data.laser_firingScatter = false; end
|
||||
end
|
||||
|
||||
function laser_getDescription(address)
|
||||
if address == nil then
|
||||
return "~not defined~"
|
||||
end
|
||||
local laser = w.device_get(address)
|
||||
if laser == nil or laser.position == nil then
|
||||
return "~invalid~"
|
||||
end
|
||||
local x, y, z = laser.position()
|
||||
return "@ " .. w.format_integer(x, 7) .. " " .. w.format_integer(y, 3) .. " " .. w.format_integer(z, 7)
|
||||
end
|
||||
|
||||
function laser_getName(address)
|
||||
return address
|
||||
end
|
||||
|
||||
function laser_battery_key(character, keycode)
|
||||
if character == 'a' or character == 'A' then -- A or keycode == 30
|
||||
table.insert(laser_batteries, {
|
||||
name = "noname",
|
||||
frequency = -1,
|
||||
headAddress = nil,
|
||||
boosterAddresses = {},
|
||||
head = nil,
|
||||
boosters = {} })
|
||||
laser_batteryIndex = #laser_batteries
|
||||
laser_battery_linkLasers()
|
||||
laser_battery_config()
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 'r' or character == 'R' then -- R or keycode == 19
|
||||
table.remove(laser_batteries, laser_batteryIndex)
|
||||
-- laser_batteryIndex = laser_batteryIndex - 1
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 'f' or character == 'F' then -- F or keycode == 33
|
||||
if data.laser_firingMode == "boosted" then data.laser_firingMode = "single"
|
||||
elseif data.laser_firingMode == "single" then data.laser_firingMode = "multi"
|
||||
elseif data.laser_firingMode == "multi" then data.laser_firingMode = "boosted" end
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 's' or character == 'S' then -- S or keycode == 31
|
||||
data.laser_firingScatter = not data.laser_firingScatter
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 'l' or character == 'L' then -- L or keycode == 38
|
||||
laser_battery_linkLasers()
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 'c' or character == 'C' then -- C or keycode == 46
|
||||
laser_battery_config()
|
||||
w.data_save()
|
||||
return true
|
||||
elseif keycode == 200 or keycode == 203 or character == '-' then -- Up or Left or -
|
||||
laser_batteryIndex = laser_batteryIndex - 1
|
||||
return true
|
||||
elseif keycode == 208 or keycode == 205 or character == '+' then -- Down or Right or +
|
||||
laser_batteryIndex = laser_batteryIndex + 1
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function laser_battery_getCurrent()
|
||||
if laser_batteries ~= nil then
|
||||
if laser_batteryIndex > #laser_batteries then
|
||||
laser_batteryIndex = 1
|
||||
elseif laser_batteryIndex < 1 then
|
||||
laser_batteryIndex = #laser_batteries
|
||||
end
|
||||
return laser_batteries[laser_batteryIndex]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function laser_battery_getByName(name)
|
||||
if laser_batteries ~= nil and name ~= nil then
|
||||
for key, laserbattery in pairs(laser_batteries) do
|
||||
if laserbattery.name == name then
|
||||
return laserbattery
|
||||
end
|
||||
end
|
||||
end
|
||||
return { frequency = -1, boosterAddresses = {}, name = "-not defined-", boosters = {} }
|
||||
end
|
||||
|
||||
function laser_battery_page()
|
||||
w.page_begin(w.data_getName() .. " - Laser batteries")
|
||||
|
||||
local laserbattery = laser_battery_getCurrent()
|
||||
|
||||
-- w.setCursorPos(1, 2)
|
||||
if #laser_batteries == 0 then
|
||||
w.setColorDisabled()
|
||||
w.writeCentered(2, "No laser battery defined, press A to add one")
|
||||
elseif laserbattery == nil then
|
||||
w.setColorWarning()
|
||||
w.writeCentered(2, "Laser battery " .. laser_batteryIndex .. " of " .. #laser_batteries .. " is not defined")
|
||||
else
|
||||
w.setColorNormal()
|
||||
w.writeCentered(2, "'" .. laserbattery.name .. "' (" .. laser_batteryIndex .. " of " .. #laser_batteries .. ")")
|
||||
|
||||
w.setCursorPos(1, 3)
|
||||
local headX = 0
|
||||
local headY = 0
|
||||
local headZ = 0
|
||||
local headFrequency = -1
|
||||
if laserbattery.head == nil then
|
||||
w.setColorDisabled()
|
||||
w.write("Laser head is not defined, press L to link one")
|
||||
else
|
||||
w.setColorNormal()
|
||||
headX, headY, headZ = laserbattery.head.position()
|
||||
headFrequency = laserbattery.head.beamFrequency()
|
||||
w.writeLn("Laser head:")
|
||||
if headFrequency == -1 then
|
||||
w.setColorWarning()
|
||||
end
|
||||
w.write(w.format_integer(headFrequency, 5))
|
||||
w.setColorNormal()
|
||||
w.write(" @ " .. w.format_integer(headX, 7) .. " " .. w.format_integer(headY, 3) .. " " .. w.format_integer(headZ, 7)
|
||||
.. " " .. string.sub(laserbattery.headAddress, 10, 100))
|
||||
end
|
||||
|
||||
w.setCursorPos(1, 5)
|
||||
if laserbattery.boosters == nil or #laserbattery.boosters == 0 then
|
||||
w.setColorDisabled()
|
||||
w.write("Boosting lasers aren't set, press L to link one")
|
||||
else
|
||||
w.setColorNormal()
|
||||
w.write("Boosting lasers:")
|
||||
for key, booster in pairs(laserbattery.boosters) do
|
||||
w.setCursorPos(1, 5 + key)
|
||||
local x, y, z = booster.position()
|
||||
if booster.beamFrequency() == headFrequency and headFrequency ~= -1 then
|
||||
w.setColorNormal()
|
||||
else
|
||||
w.setColorWarning()
|
||||
end
|
||||
w.write(w.format_integer(booster.beamFrequency(), 5))
|
||||
w.setColorNormal()
|
||||
w.write(" @ " .. w.format_integer(x - headX, 7) .. " " .. w.format_integer(y - headY, 3) .. " " .. w.format_integer(z - headZ, 7)
|
||||
.. " " .. string.sub(laserbattery.boosterAddresses[key], 10, 100))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(1, 14)
|
||||
w.write(" -----------------------------------------------")
|
||||
w.setCursorPos(1, 16)
|
||||
w.write(" Firing mode: " .. data.laser_firingMode)
|
||||
w.setCursorPos(30, 16)
|
||||
w.write("Scatter mode: ")
|
||||
if data.laser_firingScatter then
|
||||
w.setColorSuccess()
|
||||
w.write("ON")
|
||||
w.setColorNormal()
|
||||
else
|
||||
w.write("off")
|
||||
end
|
||||
|
||||
w.setColorControl()
|
||||
w.setCursorPos(1, 19)
|
||||
w.writeFullLine(" Add/Remove/Configure selected battery (A/R/C)")
|
||||
w.writeFullLine(" select battery (Arrows), Link lasers (L)")
|
||||
w.writeFullLine(" change Firing mode (F), toggle Scatter mode (S)")
|
||||
end
|
||||
|
||||
function laser_battery_config()
|
||||
local laserbattery = laser_battery_getCurrent()
|
||||
if laserbattery == nil then
|
||||
return
|
||||
end
|
||||
w.page_begin(w.data_getName() .. " - Laser battery configuration")
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(1, 3)
|
||||
w.writeLn("Battery name (" .. laserbattery.name .. "):")
|
||||
laserbattery.name = w.input_readText(laserbattery.name)
|
||||
w.setCursorPos(1, 3)
|
||||
w.clearLine()
|
||||
w.writeLn("Battery name set to " .. laserbattery.name)
|
||||
w.clearLine()
|
||||
|
||||
if laserbattery.head == nil then
|
||||
return
|
||||
end
|
||||
w.setColorDisabled()
|
||||
w.setCursorPos(1, 4)
|
||||
local headX, headY, headZ = laserbattery.head.position()
|
||||
local headFrequency = laserbattery.head.beamFrequency()
|
||||
w.write("@ " .. w.format_integer(headX, 7) .. " " .. w.format_integer(headY, 3) .. " " .. w.format_integer(headZ, 7))
|
||||
w.setCursorPos(1, 5)
|
||||
w.write("With " .. #laserbattery.boosters .. " boosters")
|
||||
|
||||
w.setCursorPos(1, 8)
|
||||
w.setColorDisabled()
|
||||
w.write(" Valid values are 0 to 65000 ")
|
||||
w.setColorNormal()
|
||||
local frequency
|
||||
repeat
|
||||
w.setCursorPos(1, 7)
|
||||
w.clearLine()
|
||||
w.write("Battery beam frequency (" .. w.format_integer(headFrequency, 5) .. "): ")
|
||||
frequency = w.input_readNumber(headFrequency)
|
||||
if frequency ~= 0 and (frequency < 0 or frequency > 65000) then
|
||||
w.status_showWarning("This is not a valid beam frequency. Try again.")
|
||||
end
|
||||
until frequency > 0 and frequency <= 65000
|
||||
w.setCursorPos(1, 8)
|
||||
w.clearLine()
|
||||
|
||||
w.setCursorPos(1, 8)
|
||||
w.clearLine()
|
||||
local newFrequency = laserbattery.head.beamFrequency(frequency)
|
||||
w.write("Head beam frequency set to " .. newFrequency)
|
||||
for key, booster in pairs(laserbattery.boosters) do
|
||||
w.setCursorPos(1, 8 + (key % 5))
|
||||
newFrequency = booster.beamFrequency(frequency)
|
||||
w.write("Booster beam frequency set to " .. newFrequency)
|
||||
end
|
||||
end
|
||||
|
||||
function laser_battery_linkLasers()
|
||||
local laserbattery = laser_battery_getCurrent()
|
||||
if laserbattery == nil then
|
||||
return
|
||||
end
|
||||
w.page_begin(w.data_getName() .. " - Linking lasers")
|
||||
|
||||
w.setColorDisabled()
|
||||
w.setCursorPos(1, 3)
|
||||
w.writeLn("Help: Use arrows to select lasers.")
|
||||
w.writeLn("Press backspace/delete to remove laser.")
|
||||
w.writeLn("Press enter to validate.")
|
||||
w.writeLn("Validate with '-no laser-' to stop adding lasers.")
|
||||
|
||||
w.setColorNormal()
|
||||
if laserbattery.boosters == nil then
|
||||
laserbattery.boosters = {}
|
||||
end
|
||||
w.writeCentered(2, "Battery '" .. laserbattery.name .. "' with " .. #laserbattery.boosters .. " boosters")
|
||||
|
||||
local laserAddresses_left = {}
|
||||
for keyAddress, laserAddress in pairs(laserAddresses) do
|
||||
laserAddresses_left[keyAddress] = laserAddress
|
||||
end
|
||||
w.setCursorPos(1, 8)
|
||||
if laserbattery.headAddress == nil then
|
||||
w.writeLn("Laser head (not defined): ")
|
||||
else
|
||||
w.writeLn("Laser head (" .. laserbattery.headAddress .. "): ")
|
||||
end
|
||||
laserbattery.headAddress = w.input_readEnum(laserbattery.headAddress, laserAddresses_left, laser_getName, laser_getDescription, "-no laser-")
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(1, 8)
|
||||
w.clearLine()
|
||||
if laserbattery.headAddress == nil then
|
||||
w.writeLn("Laser head set to (not defined)")
|
||||
laserbattery.head = nil
|
||||
else
|
||||
-- remove selected laser from potentials
|
||||
for keyLaser, laserAddress in pairs(laserAddresses_left) do
|
||||
if laser_getName(laserAddress) == laserbattery.headAddress then
|
||||
table.remove(laserAddresses_left, keyLaser)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
w.writeLn("Laser head set to " .. laserbattery.headAddress)
|
||||
laserbattery.head = w.device_get(laserbattery.headAddress)
|
||||
|
||||
w.setColorDisabled()
|
||||
w.setCursorPos(1, 9)
|
||||
local headX, headY, headZ = laserbattery.head.position()
|
||||
local headFrequency = laserbattery.head.beamFrequency()
|
||||
w.write("@ " .. w.format_integer(headX, 7) .. " " .. w.format_integer(headY, 3) .. " " .. w.format_integer(headZ, 7))
|
||||
end
|
||||
|
||||
local key = 1
|
||||
local addressCurrent = nil
|
||||
repeat
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(1, 10 + (key % 5))
|
||||
w.write("Booster #" .. key)
|
||||
addressCurrent = nil
|
||||
if key <= #laserbattery.boosterAddresses then
|
||||
addressCurrent = laserbattery.boosterAddresses[key]
|
||||
w.write(" (" .. addressCurrent .. "): ")
|
||||
else
|
||||
w.write(" (-no laser-): ")
|
||||
end
|
||||
addressCurrent = w.input_readEnum(addressCurrent, laserAddresses_left, laser_getName, laser_getDescription, "-no laser-")
|
||||
if addressCurrent == nil then
|
||||
if key > #laserbattery.boosterAddresses then
|
||||
key = -1
|
||||
else
|
||||
table.remove(laserbattery.boosterAddresses, key)
|
||||
table.remove(laserbattery.boosters, key)
|
||||
w.success("Removed")
|
||||
end
|
||||
else
|
||||
-- remove selected laser from potentials
|
||||
for keyLaser, laserAddress in pairs(laserAddresses_left) do
|
||||
if laser_getName(laserAddress) == addressCurrent then
|
||||
table.remove(laserAddresses_left, keyLaser)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
laserbattery.boosterAddresses[key] = addressCurrent
|
||||
laserbattery.boosters[key] = w.device_get(addressCurrent)
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(1, 10 + (key % 5))
|
||||
w.clearLine()
|
||||
w.write("Booster #" .. key .. " set to " .. addressCurrent)
|
||||
key = key + 1
|
||||
end
|
||||
until key == -1
|
||||
end
|
||||
|
||||
function laser_battery_getName(laserbattery)
|
||||
return laserbattery.name
|
||||
end
|
||||
|
||||
function laser_battery_getDescription(laserbattery)
|
||||
local msg = ""
|
||||
local x, y, z
|
||||
local found = false
|
||||
if laserbattery.head == nil then
|
||||
msg = msg .. 0
|
||||
else
|
||||
x, y, z = laserbattery.head.position()
|
||||
found = true
|
||||
msg = msg .. 1
|
||||
end
|
||||
msg = msg .. "+"
|
||||
if laserbattery.boosters == nil then
|
||||
msg = msg .. 0
|
||||
else
|
||||
msg = msg .. #laserbattery.boosters
|
||||
if not found then
|
||||
for key, booster in pairs(laserbattery.boosters) do
|
||||
if booster ~= nil and not found then
|
||||
x, y, z = booster.position()
|
||||
found = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return string.sub(laserbattery.name .. " ", 1, 20)
|
||||
.. msg
|
||||
.. " @ " .. w.format_integer(x, 7) .. " " .. w.format_integer(y, 3) .. " " .. w.format_integer(z, 7)
|
||||
end
|
||||
|
||||
function laser_station_key(character, keycode)
|
||||
if character == 'a' or character == 'A' then -- A or keycode == 30
|
||||
table.insert(laser_stations, { name = "noname", cameraFrequency = -1, camera = nil, batteries = {} })
|
||||
laser_stationIndex = #laser_stations
|
||||
laser_station_linkBatteries()
|
||||
laser_station_config()
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 'r' or character == 'R' then -- R or keycode == 19
|
||||
table.remove(laser_stations, laser_stationIndex)
|
||||
-- laser_stationIndex = laser_stationIndex - 1
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 'f' or character == 'F' then -- F or keycode == 33
|
||||
if data.laser_firingMode == "boosted" then data.laser_firingMode = "single"
|
||||
elseif data.laser_firingMode == "single" then data.laser_firingMode = "multi"
|
||||
elseif data.laser_firingMode == "multi" then data.laser_firingMode = "boosted" end
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 's' or character == 'S' then -- S or keycode == 31
|
||||
data.laser_firingScatter = not data.laser_firingScatter
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 'l' or character == 'L' then -- L or keycode == 38
|
||||
laser_station_linkBatteries()
|
||||
w.data_save()
|
||||
return true
|
||||
elseif character == 'c' or character == 'C' then -- C or keycode == 46
|
||||
laser_station_config()
|
||||
w.data_save()
|
||||
return true
|
||||
elseif keycode == 200 or keycode == 203 or character == '-' then -- Up or Left or -
|
||||
laser_stationIndex = laser_stationIndex - 1
|
||||
return true
|
||||
elseif keycode == 208 or keycode == 205 or character == '+' then -- Down or Right or +
|
||||
laser_stationIndex = laser_stationIndex + 1
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function laser_station_getCurrent()
|
||||
if laser_stations ~= nil then
|
||||
if laser_stationIndex > #laser_stations then
|
||||
laser_stationIndex = 1
|
||||
elseif laser_stationIndex < 1 then
|
||||
laser_stationIndex = #laser_stations
|
||||
end
|
||||
return laser_stations[laser_stationIndex]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function laser_station_page()
|
||||
w.page_begin(w.data_getName() .. " - Laser stations")
|
||||
|
||||
local laserstation = laser_station_getCurrent()
|
||||
|
||||
-- w.setCursorPos(1, 2)
|
||||
if #laser_stations == 0 then
|
||||
w.setColorDisabled()
|
||||
w.writeCentered(2, "No laser stations configured")
|
||||
elseif laserstation == nil then
|
||||
w.setColorWarning()
|
||||
w.writeCentered(2, "Laser station " .. laser_stationIndex .. " of " .. #laser_stations .. " is invalid")
|
||||
else
|
||||
w.setColorNormal()
|
||||
w.writeCentered(2, "'" .. laserstation.name .. "' (" .. laser_stationIndex .. " of " .. #laser_stations .. ")")
|
||||
|
||||
w.setCursorPos(1, 3)
|
||||
if laserstation.camera == nil then
|
||||
w.setColorDisabled()
|
||||
w.write("Laser camera is not defined, press L to link one")
|
||||
else
|
||||
w.setColorNormal()
|
||||
local camX, camY, camZ = laserstation.camera.position()
|
||||
local camVideoChannel = laserstation.camera.videoChannel()
|
||||
w.writeLn("Laser camera:")
|
||||
if camVideoChannel == -1 then
|
||||
w.setColorWarning()
|
||||
end
|
||||
w.write(w.format_integer(camVideoChannel, 5))
|
||||
w.setColorNormal()
|
||||
w.write(" @ " .. w.format_integer(camX, 7) .. " " .. w.format_integer(camY, 3) .. " " .. w.format_integer(camZ, 7)
|
||||
.. " " .. string.sub(laserstation.cameraAddress, 10, 100))
|
||||
end
|
||||
|
||||
w.setCursorPos(1, 5)
|
||||
if laserstation.batteries == nil or #laserstation.batteries == 0 then
|
||||
w.setColorDisabled()
|
||||
w.write("Laser batteries aren't set, press L to link one")
|
||||
else
|
||||
w.setColorNormal()
|
||||
w.write("Laser batteries:")
|
||||
for key, battery in pairs(laserstation.batteries) do
|
||||
w.setCursorPos(1, 5 + key)
|
||||
laserbattery = laser_battery_getByName(battery.name)
|
||||
if battery.enabled then
|
||||
w.setColorSuccess()
|
||||
else
|
||||
w.setColorDisabled()
|
||||
end
|
||||
w.write(laser_battery_getDescription(laserbattery))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(1, 14)
|
||||
w.write(" -----------------------------------------------")
|
||||
w.setCursorPos(1, 16)
|
||||
w.write(" Firing mode: " .. data.laser_firingMode)
|
||||
w.setCursorPos(30, 16)
|
||||
w.write("Scatter mode: ")
|
||||
if data.laser_firingScatter then
|
||||
w.setColorSuccess()
|
||||
w.write("ON")
|
||||
w.setColorNormal()
|
||||
else
|
||||
w.write("off")
|
||||
end
|
||||
|
||||
w.setColorControl()
|
||||
w.setCursorPos(1, 19)
|
||||
w.writeFullLine(" Add/Remove/Configure laser station (A/R/C)")
|
||||
w.writeFullLine(" select station (Arrows), Link batteries (L)")
|
||||
w.writeFullLine(" change Firing mode (F), toggle Scatter mode (S)")
|
||||
end
|
||||
|
||||
function laser_station_config()
|
||||
local laserstation = laser_station_getCurrent()
|
||||
if laserstation == nil then
|
||||
return
|
||||
end
|
||||
w.page_begin(w.data_getName() .. " - Laser station configuration")
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(1, 3)
|
||||
w.writeLn("Laser station name (" .. laserstation.name .. "):")
|
||||
laserstation.name = w.input_readText(laserstation.name)
|
||||
w.setCursorPos(1, 3)
|
||||
w.clearLine()
|
||||
w.writeLn("Laser station name set to " .. laserstation.name)
|
||||
w.clearLine()
|
||||
|
||||
if laserstation.camera == nil then
|
||||
return
|
||||
end
|
||||
w.setCursorPos(1, 5)
|
||||
local camX, camY, camZ = laserstation.camera.position()
|
||||
local camVideoChannel = laserstation.camera.videoChannel()
|
||||
w.write("Camera @ " .. w.format_integer(camX, 7) .. " " .. w.format_integer(camY, 3) .. " " .. w.format_integer(camZ, 7))
|
||||
w.setCursorPos(1, 6)
|
||||
w.write("With " .. #laserstation.batteries .. " batteries")
|
||||
|
||||
w.setCursorPos(1, 8)
|
||||
w.setColorDisabled()
|
||||
w.write(" Valid values are 0 to 268435455 ")
|
||||
w.setColorNormal()
|
||||
local channel
|
||||
repeat
|
||||
w.setCursorPos(1, 7)
|
||||
w.write("Camera video frequency (" .. w.format_integer(camVideoChannel, 5) .. "): ")
|
||||
channel = w.input_readNumber(camVideoChannel)
|
||||
if channel ~= 0 and (channel < 0 or channel > 268435455) then
|
||||
w.status_showWarning("This is not a valid video channel. Try again.")
|
||||
end
|
||||
until channel > 0 and channel <= 268435455
|
||||
w.setCursorPos(1, 8)
|
||||
w.clearLine()
|
||||
|
||||
w.setCursorPos(1, 7)
|
||||
w.clearLine()
|
||||
local newVideoChannel = laserstation.camera.videoChannel(channel)
|
||||
laserstation.camera.beamFrequency(1420)
|
||||
w.write("Camera video channel set to " .. newVideoChannel)
|
||||
|
||||
w.setCursorPos(1, 11)
|
||||
w.write("Battery enabling: ")
|
||||
for key, battery in pairs(laserstation.batteries) do
|
||||
laserbattery = laser_battery_getByName(battery.name)
|
||||
local msg = laser_battery_getDescription(laserbattery)
|
||||
|
||||
w.setCursorPos(1, 11 + (key % 5))
|
||||
if battery.enabled then
|
||||
w.setColorSuccess()
|
||||
w.write(msg)
|
||||
battery.enabled = w.input_readConfirmation("Keep battery '" .. battery.name .. "' enabled? (Y/n)")
|
||||
else
|
||||
w.setColorDisabled()
|
||||
w.write(msg)
|
||||
battery.enabled = w.input_readConfirmation("Enable battery '" .. battery.name .. "'? (Y/n)")
|
||||
end
|
||||
w.setCursorPos(1, 11 + (key % 5))
|
||||
if battery.enabled then
|
||||
w.setColorSuccess()
|
||||
w.write(msg)
|
||||
else
|
||||
w.setColorDisabled()
|
||||
w.write(msg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function laser_station_linkBatteries()
|
||||
local laserstation = laser_station_getCurrent()
|
||||
if laserstation == nil then
|
||||
return
|
||||
end
|
||||
w.page_begin(w.data_getName() .. " - Linking batteries")
|
||||
|
||||
w.setColorDisabled()
|
||||
w.setCursorPos(1, 3)
|
||||
w.writeLn("Instruction: use arrows to select batteries.")
|
||||
w.writeLn("Press backspace/delete to remove battery.")
|
||||
w.writeLn("Press enter to validate.")
|
||||
w.writeLn("Validate '-no battery-' to stop adding batteries.")
|
||||
|
||||
w.setColorNormal()
|
||||
if laserstation.batteries == nil then
|
||||
laserstation.batteries = {}
|
||||
end
|
||||
w.writeCentered(2, "Station '" .. laserstation.name .. "' with " .. #laserstation.batteries .. " batteries linked")
|
||||
|
||||
w.setCursorPos(1, 8)
|
||||
if laserstation.cameraAddress == nil then
|
||||
w.writeLn("Laser camera (not defined): ")
|
||||
else
|
||||
w.writeLn("Laser camera (" .. laserstation.cameraAddress .. "): ")
|
||||
end
|
||||
|
||||
laserstation.cameraAddress = w.input_readEnum(laserstation.cameraAddress, lasercamAddresses, laser_getName, laser_getDescription, "-no laser camera-")
|
||||
if laserstation.cameraAddress == nil then
|
||||
laserstation.camera = nil
|
||||
else
|
||||
laserstation.camera = w.device_get(laserstation.cameraAddress)
|
||||
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(1, 8)
|
||||
w.clearLine()
|
||||
w.writeLn("Laser camera set to " .. laserstation.cameraAddress)
|
||||
w.setColorDisabled()
|
||||
w.setCursorPos(1, 9)
|
||||
w.clearLine()
|
||||
local camX, camY, camZ = laserstation.camera.position()
|
||||
local camVideoChannel = laserstation.camera.videoChannel()
|
||||
w.write("@ " .. w.format_integer(camX, 7) .. " " .. w.format_integer(camY, 3) .. " " .. w.format_integer(camZ, 7))
|
||||
end
|
||||
|
||||
local key = 1
|
||||
local nameCurrent = nil
|
||||
local laser_batteries_left = {}
|
||||
for keyBattery, laserbattery in pairs(laser_batteries) do
|
||||
laser_batteries_left[keyBattery] = laserbattery
|
||||
end
|
||||
repeat
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(1, 10 + (key % 5))
|
||||
w.write("Battery #" .. key)
|
||||
nameCurrent = nil
|
||||
if key <= #laserstation.batteries then
|
||||
nameCurrent = laserstation.batteries[key].name
|
||||
w.write(" (" .. nameCurrent .. "): ")
|
||||
else
|
||||
w.write(" (-no battery-): ")
|
||||
end
|
||||
nameCurrent = w.input_readEnum(nameCurrent, laser_batteries_left, laser_battery_getName, laser_battery_getDescription, "-no battery-")
|
||||
if nameCurrent == nil then
|
||||
if key > #laserstation.batteries then
|
||||
key = -1
|
||||
else
|
||||
table.remove(laserstation.batteries, key)
|
||||
w.success("Removed")
|
||||
end
|
||||
else
|
||||
-- remove selected battery from potentials
|
||||
for keyBattery, laserbattery in pairs(laser_batteries_left) do
|
||||
if laser_battery_getName(laserbattery) == nameCurrent then
|
||||
table.remove(laser_batteries_left, keyBattery)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
laserstation.batteries[key] = { name = nameCurrent, enabled = true }
|
||||
w.setColorNormal()
|
||||
w.setCursorPos(1, 10 + (key % 5))
|
||||
w.clearLine()
|
||||
w.write("Battery #" .. key .. " set to " .. nameCurrent)
|
||||
key = key + 1
|
||||
end
|
||||
until key == -1
|
||||
end
|
||||
|
||||
function laser_battery_shoot(batteryName, targetX, targetY, targetZ)
|
||||
local laserbattery = laser_battery_getByName(batteryName)
|
||||
|
||||
if laserbattery == nil then
|
||||
w.status_showWarning("Invalid battery name '" .. batteryName .. "'")
|
||||
return
|
||||
end
|
||||
|
||||
local x, y, z
|
||||
if data.laser_firingMode == "boosted" and laserbattery.head ~= nil and laserbattery.boosters ~= nil then
|
||||
local frequency = laserbattery.head.beamFrequency()
|
||||
local headX, headY, headZ = laserbattery.head.position()
|
||||
|
||||
for key, booster in pairs(laserbattery.boosters) do
|
||||
booster.beamFrequency(frequency)
|
||||
end
|
||||
w.sleep(0)
|
||||
for key, booster in pairs(laserbattery.boosters) do
|
||||
x, y, z = booster.position()
|
||||
booster.emitBeam(headX - x, headY - y, headZ - z)
|
||||
end
|
||||
w.sleep(0.1)
|
||||
if data.laser_firingScatter then
|
||||
headX = headX + math.random(-1, 1)
|
||||
headY = headY + math.random(-1, 1)
|
||||
headZ = headZ + math.random(-1, 1)
|
||||
end
|
||||
laserbattery.head.emitBeam(targetX - headX, targetY - headY, targetZ - headZ)
|
||||
elseif data.laser_firingMode == "single" and laserbattery.head ~= nil then
|
||||
x, y, z = laserbattery.head.position()
|
||||
if data.laser_firingScatter then
|
||||
x = x + math.random(-1, 1)
|
||||
y = y + math.random(-1, 1)
|
||||
z = z + math.random(-1, 1)
|
||||
end
|
||||
laserbattery.head.emitBeam(targetX - x, targetY - y, targetZ - z)
|
||||
else
|
||||
if laserbattery.head ~= nil then
|
||||
x, y, z = laserbattery.head.position()
|
||||
if z ~= nil then
|
||||
if data.laser_firingScatter then
|
||||
x = x + math.random(-1, 1)
|
||||
y = y + math.random(-1, 1)
|
||||
z = z + math.random(-1, 1)
|
||||
end
|
||||
laserbattery.head.emitBeam(targetX - x, targetY - y, targetZ - z)
|
||||
end
|
||||
end
|
||||
|
||||
if laserbattery.boosters ~= nil then
|
||||
for key, booster in pairs(laserbattery.boosters) do
|
||||
x, y, z = booster.position()
|
||||
if z ~= nil then
|
||||
if data.laser_firingScatter then
|
||||
x = x + math.random(-1, 1)
|
||||
y = y + math.random(-1, 1)
|
||||
z = z + math.random(-1, 1)
|
||||
end
|
||||
booster.emitBeam(targetX - x, targetY - y, targetZ - z)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function laser_boot()
|
||||
-- nothing
|
||||
end
|
||||
|
||||
function laser_sendEvent()
|
||||
if #laser_stations == 0 then
|
||||
w.status_showWarning("No laser station configured")
|
||||
elseif #laser_batteries == 0 then
|
||||
w.status_showWarning("No laser battery configured")
|
||||
else
|
||||
w.status_showWarning("Laser sent!")
|
||||
for keyStation, laserstation in pairs(laser_stations) do
|
||||
if laserstation.camera ~= nil then
|
||||
local resType, x, y, z, id, meta, res = laserstation.camera.getScanResult()
|
||||
if res ~= -1 then
|
||||
w.status_showWarning("Firing at " .. x .. " " .. y .. " " .. z)
|
||||
for batteryKey, battery in pairs(laserstation.batteries) do
|
||||
if battery.enabled then
|
||||
laser_battery_shoot(battery.name, x, y, z)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function laser_register()
|
||||
w.device_register("warpdriveLaserCamera",
|
||||
function(deviceType, address, wrap) table.insert(lasercamAddresses, address) end,
|
||||
function() end)
|
||||
w.device_register("warpdriveLaser",
|
||||
function(deviceType, address, wrap) table.insert(laserAddresses, address) end,
|
||||
function() end)
|
||||
w.event_register("laserScanning", function() laser_sendEvent() return false end )
|
||||
w.event_register("laserSend" , function() return false end )
|
||||
w.data_register("laser", laser_read, laser_save)
|
||||
end
|
||||
|
||||
----------- connections status
|
||||
|
||||
function connections_page(isBooting)
|
||||
w.page_begin(w.data_getName() .. " - Connections")
|
||||
|
||||
w.writeLn("")
|
||||
|
||||
if #laserAddresses == 0 then
|
||||
w.setColorDisabled()
|
||||
w.writeLn("No attack laser detected")
|
||||
elseif #laserAddresses == 1 then
|
||||
w.setColorSuccess()
|
||||
w.writeLn("1 attack laser detected")
|
||||
else
|
||||
w.setColorSuccess()
|
||||
w.writeLn(#laserAddresses .. " attack lasers detected")
|
||||
end
|
||||
|
||||
if #lasercamAddresses == 0 then
|
||||
w.setColorDisabled()
|
||||
w.writeLn("No laser camera detected")
|
||||
elseif #lasercamAddresses == 1 then
|
||||
w.setColorSuccess()
|
||||
w.writeLn("1 laser camera detected")
|
||||
else
|
||||
w.setColorSuccess()
|
||||
w.writeLn(#lasercamAddresses .. " laser cameras detected")
|
||||
end
|
||||
|
||||
if isBooting then
|
||||
laser_boot()
|
||||
end
|
||||
|
||||
w.writeLn("")
|
||||
w.setColorNormal()
|
||||
w.writeLn("This is a keyboard controlled user interface.")
|
||||
w.write("Key controls are written like so: ")
|
||||
w.setColorControl()
|
||||
w.write("Action (key)")
|
||||
w.setColorNormal()
|
||||
w.writeLn(".")
|
||||
w.write("For example, typing ")
|
||||
w.setColorControl()
|
||||
w.write(" 1 ")
|
||||
w.setColorNormal()
|
||||
w.writeLn(" will open Laser batteries.")
|
||||
end
|
||||
|
||||
----------- Boot sequence
|
||||
|
||||
w.page_setEndText(" Home (0), Laser batteries (1), Laser stations (2)")
|
||||
w.page_register('0', connections_page, nil)
|
||||
w.page_register('1', laser_battery_page, laser_battery_key)
|
||||
w.page_register('2', laser_station_page, laser_station_key)
|
||||
laser_register()
|
||||
|
||||
w.boot()
|
||||
w.run()
|
||||
w.close()
|
Loading…
Add table
Reference in a new issue