LUA Factory Control
--[[

Factory Control for FTB

types: buttons
 @desc the array of global buttons indexed by name

 button[name] = {
 text the text displayed
 state if it os "on" or "off"
 func the function called if the button is activated
 origx the top right x
 origy the top right y
 width width of the button
 height height of the button
 padx padding to add to the left and right sides
 pady padding to add to the top and bottom
 foreground text color
 background bg color
 }

 a 'box' object is simpy an alignment rectangle, the default
 is the 'window' object and is initialized by the initMon routine
 it is used by alignment routines for control objects "buttons"

 box {
 o { origin 
 x
 y
 }
 w width
 h height
 }

]]--


-- Locals
local version = "1.0"
local running = true
local mon = ""
local buttons = {}
local window = {}
local outBundleSide = "left"

function initMon(side)
 mon = peripheral.wrap(side)
 mon.setTextScale(1)
 mon.setBackgroundColor(colors.black)
 mon.setTextColor(colors.white)
 window["o"] = {}
 window["o"]["x"] = 1
 window["o"]["y"] = 1
 window["w"], window["h"] = mon.getSize()
end

function updateButtonCalc( button )
 button["tlen"] = string.len( button["text"] )
 button["height"] = button["pady"] * 2 + 1
 button["width"] = button["padx"] * 2 + button["tlen"]
 button["xend"] = button["origx"] + button["width"] - 1
 button["yend"] = button["origy"] + button["height"] - 1
 button["tX"] = button["origx"] + (math.floor( button["width"] / 2 ) - math.floor( button["tlen"] / 2 )) - 1 + button["padx"]
 button["tY"] = button["origy"] + math.floor( button["height"] / 2 )
end

function addButton( name, text, func, state, origx, origy, padx, pady, fore, bact, binact )
 buttons[name] = {}
 buttons[name]["text"] = text
 buttons[name]["state"] = state
 buttons[name]["defstate"] = state
 buttons[name]["func"] = func
 buttons[name]["origx"] = origx
 buttons[name]["origy"] = origy
 buttons[name]["padx"] = padx
 buttons[name]["pady"] = pady
 buttons[name]["foreground"] = fore
 buttons[name]["bact"] = bact
 buttons[name]["binact"] = binact
 
 updateButtonCalc(buttons[name])
end

function addSimpleButton( name, text, func, origx, origy )
 addButton( name, text, func, false, origx, origy, 1, 1, colors.white, colors.cyan, colors.red )
end

function drawButton( bData )
 local tLen = bData["tlen"]
 local h = bData["height"]
 local w = bData["width"]
 local xend = bData["xend"]
 local yend = bData["yend"]
 local tY = bData["tY"]
 local tX = bData["tX"]

 if bData["state"] == true then
 mon.setBackgroundColor( bData["bact"] )
 else
 mon.setBackgroundColor( bData["binact"] )
 end
 mon.setTextColor( bData["foreground"] )

 for i = bData["origy"], yend do
 mon.setCursorPos( bData["origx"], i )
 if i == tY then
 for j = bData["origx"], (xend - tLen + 1) do
 if j == tX then
 mon.write(bData["text"])
 else
 mon.write(" ")
 end
 end
 else
 for i = bData["origx"], xend do
 mon.write(" ")
 end
 end
 end
 mon.setBackgroundColor( colors.black )
end

function drawButtons()
 for name,data in pairs(buttons) do
 drawButton( data )
 end
end

function heading( text )
 w, h = mon.getSize()
 mon.setCursorPos( (w-string.len(text))/2+1, 1 )
 mon.write( text )
end

function drawScreen( )
 mon.clear()
 heading("Factory Control v"..version)
 drawButtons()
end

function toggleButton(name)
 buttons[name]["state"] = not buttons[name]["state"]
end

--[[ for alignment, horiz and vert can have 3 states:
 0 no change
 1 left/top
 2 right/bottom
 3 center
]]--

function alignButtonInBox( button, box, horiz, vert )
 local x = box["o"]["x"]
 local y = box["o"]["y"]
 
 if horiz > 0 then
 if horiz == 1 then
 button["origx"] = x
 elseif horiz == 2 then
 x = (x + box["w"] - 1) - button["width"]
 button["origx"] = x
 elseif horiz == 3 then
 x = x + (box["w"] / 2)
 button["origx"] = x
 end
 end

 if vert > 0 then
 if vert == 1 then
 button["origy"] = y
 elseif vert == 2 then
 y = (y + box["h"] - 1) - button["height"]
 button["origy"] = y
 elseif vert == 3 then
 y = y + (box["h"] / 2)
 button["origy"] = y
 end
 end

 updateButtonCalc( button )

end

function powerDown()
 print("shutting down...")
 running = false
end

-- the nuke is using white for its color
function toggleNuclear(name)
 local mcol = colors.white
 local ccol = rs.getBundledOutput(outBundleSide)
 local button = buttons[name]

 if button["state"] == false then
 print("turning "..name.." on")
 button["state"] = true
 local ac = colors.combine( ccol, mcol )
 rs.setBundledOutput(outBundleSide, ac)
 else
 print("turning "..name.." off")
 button["state"] = false
 local ac = colors.subtract( ccol, mcol )
 rs.setBundledOutput( outBundleSide, ac )
 end
end

function toggleMJLava(name)
 local mcol = colors.blue
 local ccol = rs.getBundledOutput(outBundleSide)
 local button = buttons[name]

 if button["state"] == false then
 button["state"] = true
 local ac = colors.combine( ccol, mcol )
 rs.setBundledOutput(outBundleSide, ac)
 else
 button["state"] = false
 local ac = colors.subtract( ccol, mcol )
 rs.setBundledOutput( outBundleSide, ac )
 end
end

-- note, the elec connectoin isn't on
function toggleMJElec(name)
 local mcol = colors.green
 local ccol = rs.getBundledOutput(outBundleSide)
 local button = buttons[name]

 if button["state"] == false then
 button["state"] = true
 local ac = colors.combine( ccol, mcol )
 rs.setBundledOutput(outBundleSide, ac)
 else
 button["state"] = false
 local ac = colors.subtract( ccol, mcol )
 rs.setBundledOutput( outBundleSide, ac )
 end
end

function toggleMassFab(name)
 local mcol = colors.black
 local ccol = rs.getBundledOutput(outBundleSide)
 local button = buttons[name]

 if button["state"] == false then
 button["state"] = true
 local ac = colors.combine( ccol, mcol )
 rs.setBundledOutput(outBundleSide, ac)
 else
 button["state"] = false
 local ac = colors.subtract( ccol, mcol )
 rs.setBundledOutput( outBundleSide, ac )
 end
end

function toggleFarms(name)
 local mcol = colors.pink
 local ccol = rs.getBundledOutput(outBundleSide)
 local button = buttons[name]

 if button["state"] == false then
 print("turning "..name.." on")
 button["state"] = true
 local ac = colors.combine( ccol, mcol )
 rs.setBundledOutput(outBundleSide, ac)
 else
 print("turning "..name.." off")
 button["state"] = false
 local ac = colors.subtract( ccol, mcol )
 rs.setBundledOutput( outBundleSide, ac )
 end
end

function toggleQuarry(name)
 local mcol = colors.lightBlue
 local ccol = rs.getBundledOutput(outBundleSide)
 local button = buttons[name]

 if button["state"] == false then
 print("turning "..name.." on")
 button["state"] = true
 local ac = colors.combine( ccol, mcol )
 rs.setBundledOutput(outBundleSide, ac)
 else
 print("turning "..name.." off")
 button["state"] = false
 local ac = colors.subtract( ccol, mcol )
 rs.setBundledOutput( outBundleSide, ac )
 end
end

function toggleMFFSExt(name)
 local mcol = colors.gray
 local ccol = rs.getBundledOutput(outBundleSide)
 local button = buttons[name]

 if button["state"] == false then
 print("turning "..name.." on")
 button["state"] = true
 local ac = colors.combine( ccol, mcol )
 rs.setBundledOutput(outBundleSide, ac)
 else
 print("turning "..name.." off")
 button["state"] = false
 local ac = colors.subtract( ccol, mcol )
 rs.setBundledOutput( outBundleSide, ac )
 end
end

function initButtons()
 addSimpleButton( "nuke", "Nuclear Power", toggleNuclear, 1, 3 )
 addSimpleButton( "mjlava", "MJ Lava Power", toggleMJLava, 1, 7)
 addSimpleButton( "mjelec", "MJ Elec Power", toggleMJElec, 2 + buttons["mjlava"]["xend"], 7 )
 addSimpleButton( "farms", " Farm Power ", toggleFarms, 1, 11 )
 addSimpleButton( "quarry", "Tesser Power", toggleQuarry, 2 + buttons["farms"]["xend"], 11 )
 -- addSimpleButton( "mffsext","MFFS Extractor", toggleMFFSExt, 2 + buttons["quarry"]["xend"], 11 )

 addSimpleButton( "power", "(|)", powerDown, 1, 3 )
 buttons["power"]["binact"] = colors.purple
 alignButtonInBox( buttons["power"], window, 2, 0 )

 addSimpleButton( "massfab", "Mass Fabricator", toggleMassFab, 1, 7 )
 alignButtonInBox( buttons["massfab"], window, 2, 0 )

end

function checkButtonHit( x, y )
 for name, data in pairs(buttons) do
 if y >= data["origy"] and y <= data["yend"] then
 if x >= data["origx"] and x <= data["xend"] then
 data["func"](name)
 end
 end
 end
end

function shutdownButtons()
 for name, data in pairs(buttons) do
 if data["state"] ~= data["defstate"] then
 data["func"](name)
 end
 end
end

-- current mon is 50x19

print("Factory Control v"..version.." starting up...")

function handleRSEvent()
 local ccolors = rs.getBundledInput(outBundleSide)
 if colors.test( ccolors, colors.purple ) then
 if buttons["nuke"]["state"]== false then
 toggleNuclear("nuke")
 end
 else
 if buttons["nuke"]["state"] == true then
 toggleNuclear("nuke")
 end
 end
end

function handleEvents()
 while running == true do
 drawScreen()
 local e, side, x, y = os.pullEvent()
 if e == "monitor_touch" then
 checkButtonHit( x, y )
 elseif e == "redstone" then
 handleRSEvent()
 else
 print("received event "..e)
 end
 sleep( .1 )
 end
end

rs.setOutput("top", true) -- turn on the "i'm on" output
initMon("right")
initButtons()

handleEvents()

shutdownButtons()
rs.setOutput("top", false) -- turn off "i'm on" output
mon.clear()

About

Agathezol is a gamer, programmer, father, husband, and musician. When he's not writing blog posts nobody reads he generally writes protocol stacks, network code, and core telecommunications software but has dabbled in game design, web programming, mobile device software, and desktop software.

Categories: Minecraft