- Sky
- Blueberry
- Slate
- Blackcurrant
- Watermelon
- Strawberry
- Orange
- Banana
- Apple
- Emerald
- Chocolate
- Charcoal
-
Content Count
451 -
Joined
-
Last visited
-
Days Won
35
Posts posted by Molinko
-
-
Thanks. It's always referenced as 'the' newline char
-
Start from scratch. Install OpenOS on fresh hardware. Reboot. Then create your directories and whatnot.
-
I believe term.read returns its input with a newline char (\n) appended to the end of its output. So, typing 'exit' would return 'exit\n'.
One option is to use io.read if you don't need all of the options term.read offers. io.read will return the input without a newline. Or, you can
strip the newline and compare as usual.
local input = term.read() if input:sub(-2) == 'exit' then -- # I believe input:sub(-2) should strip the last two chars (\n) from the input variable... end
-
Have you tried getting the robot to pull from specific sides of the block? Some blocks robot can only pull from a specific side.
-
When you're dumb and overlook the obvious.. thanks. I don't know why I didn't think of that...
-
It's pretty hard to tell where exactly this is coming from. I dont have br and im too lazy to install a modpack with it.... However, I would usggest littering your code with print statements to see where specifically the code is failing... Try this and see if provides any clues...
local modem=component.proxy(component.list("modem")()) local turbine=component.proxy(component.list("br_turbine")()) modem.open(1) local target = false print "main loop start." while true do local e, to, from, _, _, command = computer.pullSignal() if e == "modem_message" then print("modem_message event. from: '" .. from .. "'") if command == "s" then print "'s' command. sending handshake." modem.send(from,1, "Handshake") local target = from elseif command == "a" then print "active command" if (turbine.getActive()) then turbine.setActive(false) print "turbine inactive" else turbine.setActive(true) print "turbine active" end elseif command == "c" then print "inductor command" if (turbine.getInductorEngaged()) then print "inductor disengaged" turbine.setInductorEngaged(false) else print "inductor engaged" turbine.setInductorEngaged(true) end elseif (target) then print "target... how did we get here..." local data1 = tostring(turbine.getActive()) local data2 = tostring(turbine.setInductorEngaged()) local data3 = tostring(turbine.getRotorSpeed()) print("sending turbine data to target") print("target: " .. (type(target)=="string" and target or "target should be string not bool..")) modem.send(target,1, data1, data2, data3) end end end print "we made it..."
-
I'm pretty sure your problem is here..
data1 = pct -- pct is nil data2 = nrj -- nrj is nil data3 = nrjMax -- nrjMax is nil gpu.set(4,8,nrj) -- This is where the error comes from. "Bad Argument #3 (string expected, got nil.)"... gpu.set(4,10,nrjMax) -- so on.. gpu.set(4,12,pct) -- and so on..
Nowhere in the above code you supplied did you define the values of pct, nrj, or nrjMax. So, they are nil.
-
From looking at the modem component API you should be able to send up to 8 basic datums in each message. From what I can see in your example It should work fine sending. Could you post your receiving code? The 'modem_message' event has 5 return values before the data you've sent.
local _event, localAddress, remoteAddress, portNumber, distance, sentData1, sentData2, sentData3, sentData4 = event.pull("modem_message")
-
I'm sorry for the headache rather than the help..
local component = require("component") local sides = require("sides") local event = require("event") local term = require("term") local thread = require("thread") local rs = component.redstone local gpu = component.gpu -- Config local delay, isOpen = 5, (rs.getOutput(sides.right) > 0) and true or false local timer = nil term.clear() term.setCursor(1, 1) gpu.setForeground(0x00FF00) print("--------------------------- ToNELvision MICROSYTEMS ---------------------------\n") gpu.setForeground(0xFFFFFF) print("Welcome. Please enter one of the displayed commands. It may take a few seconds for the command to be interpreted.\n") gpu.setForeground(0xE6AB38) print("Open\nClose") term.setCursor(1, 9) local inputThread inputThread = thread.create(function() while true do local input = term.read(nil, false) if type(input) == "string" then input = input:sub(1, -2) elseif type(input) == "boolean" and input == false then print("interrupted") inputThread:kill() end term.clearLine() if input == "open" or input == "Open" then if not isOpen then rs.setOutput(sides.right, 15) isOpen = true if timer then event.cancel(timer) end timer = event.timer(delay, function() if isOpen then rs.setOutput(sides.right, 0) isOpen = false timer = nil end end) end elseif input == "close" or input == "Close" then if isOpen then rs.setOutput(sides.right, 0) event.cancel(timer) isOpen = false end elseif input == "quit" or input == "Quit" then inputThread:kill() end end end) local motionThread = thread.create(function() while true do local _, _, x, y, name = event.pull("motion") if not isOpen then rs.setOutput(sides.right, 15) isOpen = true if timer then event.cancel(timer) end timer = event.timer(delay, function() if isOpen then rs.setOutput(sides.right, 0) isOpen = false timer = nil end end) else event.cancel(timer) timer = event.timer(delay, function() if isOpen then rs.setOutput(sides.right, 0) isOpen = false timer = nil end end) end end end) thread.waitForAny({inputThread, motionThread}) print("\nProgram Exit") os.exit()
Tested... sorry for the headache...
-
3 hours ago, deace_nuts said:
I see, I've noticed that the motion sensor works, but neither Open nor Quit does anything.
I edited the original script in my post. I'm confident I fixed open() however I'm not sure if threads can call thread:kill() from within themselves.. So quitting may still be bugged :/
-
The thread library is included in later versions of openos. Check the forums for openos updater. Download it with internet card. Install it. Lemme know how it goes.
-
local component = require("component") local sides = require("sides") local event = require("event") local term = require("term") local thread = require("thread") local rs = component.redstone local gpu = component.gpu -- Config local delay = 5 local function open() rs.setOutput(sides.right, 15) os.sleep(delay) rs.setOutput(sides.right, 0) end local inputThread inputThread = thread.create(function() while true do term.clear() term.setCursor(1, 1) gpu.setForeground(0x00FF00) print("--------------------------- ToNELvision MICROSYTEMS ---------------------------\n") gpu.setForeground(0xFFFFFF) print("Welcome. Please enter one of the displayed commands. It may take a few seconds for the command to be interpreted.\n") gpu.setForeground(0xE6AB38) print("Open\nClose") term.setCursor(1, 9) local input = term.read() if input == "open" or input == "Open" then open() elseif input == "quit" or input == "Quit" then inputThread:kill() end end end) local motionThread = thread.create(function() while true do local _, _, x, y, name = event.pull("motion") open() end end) thread.waitForAny({inputThread, motionThread}) print("\nProgram Exit")
This is and example using payonels thread api. I haven't used it yet myself but it is very powerful. Hats off to payonel for this one.
If this example has a bug, (its untested), lets me know the error and ill try to remedy it..
-
The motion sensor must be in line of sight. Solid blocks and maybe even doors will keep the motion sensor from triggering. From a glance the code seems like it should work as expected...
-
Fuckin lovely
-
This is wonderfully done and wonderfully useful! I love this reactive style of programming. Would you mind sharing some files of SAD Actors and Queries you've written? I'd love to dig in a bit more if you dont mind..
-
If you use the network loot disk I believe you can call network.icmp.bind('something'). That address will only be recognized by other computers using the network program
-
The or keyword is binary and can only work on two variables. Each function you have is returning multiple values and only the first of each are being used and assigned.
-
There seems to be a bug in the term lib loading a tty window. I think perhaps tty isnt fully loaded yet..? Try using term.read instead of io.. Maybe that'll help... If you get a new error that'd be helpful.
-
7 minutes ago, Fingercomp said:
When I was writing that response, I didn't really know, well, how experienced you are at Lua programming.
Thanks, you're nice . It was my first language.
7 minutes ago, Fingercomp said:OOP in general, not in Lua, isn't really advanced. Many languages allow to write in object-oriented style. To name a few: Java, Python, C++. If you don't know what OOP is, writing a few programs in these languages can help to understand the subject.
^^^ THIS. So much yes. I had a hard time grasping the concept of OOP at first because Lua doesn't have many of the features an OO language like Java and so on..
Personally an OOP-like library is the only real practical way in my opinion to even use OO in Lua. Writing actual program logic doesn't work so well this way.. Gets bloated quick. BUT, an OO library is easy to extend for a use case should you need it.
13 minutes ago, Fingercomp said:It's just me searching for the greatest library possible, and someone would need quite a lot of Lua experience to create a library I would be satisfied with.
Oh boy I've been trying forever to get this right. When I do I'll let you know .
15 minutes ago, Fingercomp said:If you can't do OOP, do what you can, or you can easily lose the motivation. Create the library you want, not I. Your current way is very beginner-friendly, so Lua beginners might use it
I agree. I just wanted to show you how big the world is... lol. If you really want to twist your brain for the better check out Functional programming. Also, a useful mind-fuck. As for the intended style Lua was built for... I believe its intended to be Procedural with a dash of meta-programming. As I said earlier, Lua was my first and still my favorite.
This has been a nice discussion .
-
yeah.. I was worried it might just look like spaghetti...
3 hours ago, Dustpuppy said:Don't you think it is too complicated for the normal user? Most people using lua in OC are beginners , not coders. Even it is complicated to me, i am talking about the normal player, who just want to put some information on his screen.
Yes and No. Yes. The user of the library doesn't need or want to know how the library works to be able to use it and shouldn't have to either. No, because anyone like @Fingercomp who might like to use your library, even if it lacks a specific element, might like to be able to integrate a custom element and not have to write an entire library to do it. A good example would be to think of how similar a 'Label' and a 'Button' object are to each other. They can share ~90% of their code, so why rewrite the other 90% of a button if its just like a label with a touch event listener.
-- # ... more gui shit above.. local Label = {} Label.__index = Label function Label:draw(fg, bg) local ofg, obg = gpu.setForground(fg), gpu.setBackground(bg) -- # self here refers to the label instance. The specific label calling draw. Label:draw is really a shorcut for Label.draw(labelInstance, fg, bg) gpu.fill(self.x, self.y, self.width, self.height, " ") -- # draw the box gpu.set( math.floor((self.x + self.width - 1) / 2 + #self.text / 2 + .5), math.floor(self.height / 2 + .5), self.text ) -- # center the label text. ugly gpu.setForground(ofg) -- # reset the fg and bg colors gpu.setBackground(obg) end local function newLabel(x, y, text, w, h) return setmetatable({ x = x, y = y, text = text, width = w, height = h }, Label) end local Button = setmetatable({}, {__index = Label}) -- # look to Label for :draw method Button.__index = Button local function newButton(x, y, text, w, h, action) local button = newLabel(x, y, text, w, h) button.action = action local listener = function(...) local _, x, y = ... if x >= self.x and x <= self.x + self.width - 1 then if y >= self.y and y <= self.y + self.height - 1 then action() end end end event.listen('touch', listener) -- # this is easy for the demo here but can be a memory leak if left after the program ends... return setmetatable(button, Button) end -- # End
I hope this example, although not much less complicated, will help convey the point.
-
@Fingercomp makes a great point.
1 hour ago, Fingercomp said:Why not use OOP? So that GUI elements could be modified in some way by calling its method (...)
Without trying to use too much jargon.. OOP or Object Oriented Programming is a style of program or library organization that pairs 'Classes' with 'Instances'.
This is hard to explain so I'll use an example that hopefully will demonstrate why OOP can be a powerful paradigm and useful to learn.
-- # Person. Our 'Base' class for a set of more complex classes. local Person = {} -- # Use Person(name, age, sex) to use as an instance constructor. Person.__index = Person setmetatable(Person, { __call = function(_, name, age, sex) local person = { name = name, age = age, sex = sex } return setmetatable(person, Person) end }) function Person:introduce() return ("Hello, my name is %s."):format(self.name) end function Person:greet(otherPerson) return self:introduce() .. (" Nice to meet you %s."):format(otherPerson.name) end -- # Now we can create 'Persons' or 'instances' of Persons as we call them in OOP. local bob = Person('Bob', 49, 'male') local jane = Person('Jane', 33, 'female') print( bob:greet(jane) ) -- # > "Hello, my name is Bob. Nice to meet you Jane." -- # This is where OOP really shines and why it would be recommeneded. 'Inheritance'. local Wizard = {} Wizard.__index = Wizard setmetatable(Wizard, { __call = function(_, name, age, sex, spells) local wizard = Person(name, age, sex) -- # create a wizard from the Person class. Wizards are people too. Not all People are Wizards. wizard.spells = spells -- # Wizard specific return setmetatable(wizard, Wizard) -- # bestow Wizard methods upon wizard instance. end, -- # inheritance __index = Person -- # If a method or field isn't within a 'Wizard' then fallback to the 'Base' which is 'Person'. i.e wizardInstance:greet(bob) }) -- # Sub-class method override. function Wizard:introduce() -- # Wizard introductions should state the prestige that they are Wizards! return ("Hello, my name is %s the wizard."):format(self.name) end -- # Wizard:greet is inherited from Person. function Wizard:cast(spell, target) assert(self.spells[spell], "Invalid spell. Your Wizard is weak.") return ("%s the wizard casts '%s' upon %s for %d damage."):format(self.name, spell, target.name, self.spells.damage) end local merlin = Wizard("Merlin", 61, "male", { ["Abbra"] = { name = "Abbra", damage = 12 } }) -- # Notice :greet() is inherited from Person class but uses the merlin instances version of :introduce() print( merlin:greet(bob) ) -- # > "Hello, my name is Merlin the wizard. Nice to meet you Bob." print( merlin:cast('Abbra', bob) ) -- # > "Merlin the wizard casts 'Abbra' upon Bob for 12 damage." -- # End
I hope this example can illustrate to you the advantages of OOP design. Any questions? ask away
-
This looks great. Taking @Nexarius ' advice is a good idea. No term.clear(). bad, badbadbad. This makes the flicker. This angers the gods.
Also, I would suggest using a gui library. Maybe @Gophers' GML or Zer0Galaxys' libforms. One more suggestion would definitely be, again @Nexarius suggestion, to use a lookup table rather than the long if-else chains you have set up. This would help with functions like 'reactorDataTable()' or 'captureKeys()'.
-
I think Gorzoid means a 'debug' card
-
You should check out what openOS does for require. Here.
Specifically the package library
Check out What's available. <-here
Above its what's in the bare lua environment without a loaded os
thread question #2
in Programming
Posted
Please post all your code. In code tags please.