Why does my lua script print both values? - lua

first of all, this is my first time coding in Lua, let alone coding at all.
I'm testing out lua for making some mods, and I can't really figure out what i'm doing wrong. I'm trying to get my script to say 2 different things with 2 different values, but lua keeps printing BOTH values.
Here is my code:
sword = unequipped
if sword == equipped then
print("This feels quite heavy")end
if sword == unequipped then
print("I feel unstoppable")
end
When I run the script, it prints out both values, so in terminal, it says;
This feels quite heavy
I feel unstoppable
How can i fix this?
Thanks in advance!

I suspect your problem is you haven't defined unequipped or equipped so they are both nil so sword is equal to both of them.
In general when you have a problem like this, try using the interactive interpreter. e.g.
bash-3.2$ lua
Lua 5.2.4 Copyright (C) 1994-2015 Lua.org, PUC-Rio
> sword = unequipped
> print(sword)
nil
> print(equipped)
nil
> print(sword == equipped)
true

Related

What lua metamethod is being called here?

I was doing some anti metamethod hooks and I was curious on what metamethod is called in the code below between the parentheses
local test = "random string"
if (test == "random string") then --// What metamethod if any is being called here?
print("equals")
end
I've done some research and took a look at the __eq metamethod, but that is only called when comparing two tables which isn't what I'm tryna do.
If there isn't any metamethod being called then how would I protect the if condition?
-- Update --
What if I put every string inside of a table for example:
local _Table1 = {"Test1", "Test2"}
local _Table2 = {"Test1", "Test2"}
for Index, Value in next, _Table1 do
if Value == _Table2[Index] then
print("Tables Match!")
elseif Value ~= _Table2[Index]
print("Tables Don't Match!")
end
end
I'm not doing any string converting here, but I'm showing what I could try and do for a simple anti tamper.
The only operator in the parenthesized expression is ==. Thus the only metamethod in question is __eq. The Lua Reference Manual states the following on __eq:
__eq: the equal (==) operation. Behavior similar to the addition operation, except that Lua will try a metamethod only when the values being compared are either both tables or both full userdata and they are not primitively equal.
Your values are strings and thus no metamethod will be called - even if you were to modify the string metatable to alter __eq.
Strings in Lua are always interned, so this comparison will always run in constant time. Since it is a primitive comparison, it can't possibly throw an error. No metamethod is called.
There is nothing to protect from: No possible performance issue / DoS vulnerability, no possible fancy side effects or code execution, no possible error.
(Highly theoretically: If a debug hook running every n instructions is registered, it might fire as the comparison is executed. You can hardly "protect" against a debug hook though.)
But it makes sense, for example a check against the Length.
A check against the Content seems also possible but need more lines.
And i like one liner in Lua Standalone to show...
> _VERSION
Lua 5.4
> eqtab = setmetatable({"Test1", "Test2"}, {__eq = function(left, right) print('SIMON SAYS:') return(#left == #right) end})
> eqtab == {1}
SIMON SAYS:
false
> eqtab == {}
SIMON SAYS:
false
> eqtab == {"Test1", "Test2"}
SIMON SAYS:
true
> eqtab == {1, 2}
SIMON SAYS:
true

Is there a reason why this code is not outputting a worth

Problem
Hello, StackOverflow community! I am working on this Lua game, and I was testing to see if it would change the text on my TextLabel to the Bitcoins current worth, I was utterly disappointed when nothing showed up.
I have tried to do research on Google, and my code seems to be just right.
Code
Change = false
updated = false
while Change[true] do --While change = true do
worth = math.random(1,4500) --Pick random number
print('Working!') --Say its working
Updated = true --Change the updated local var.
end --Ending while loop
script.Parent.TextLabel.Text.Text = 'Bitcoin is currently worth: ' .. worth
--Going to the Text, and changing in to a New worth.
while Updated[false] do --While updated = false do
wait(180) --Wait
Change = true --After waits 3 minutes it makes an event trigger
end -- Ending while loop
wait(180) --Wait
Updated = false --Reseting Script.
I expect the output on the Label to be a random number.
I can't really speak to roblox, but there are a couple of obvious problems with your code:
Case
You have confusion between capitalized ("Updated", "Change") and lowercase ("updated", "change" [in commented while statement]), which will fail. See, for example:
bj#bj-lt:~$ lua
Lua 5.2.4 Copyright (C) 1994-2015 Lua.org, PUC-Rio
> Updated = true
> print(Updated)
true
> print(updated)
nil
So be super-careful about what identifiers you capitalize. In general, most programmers leave variables like that in all-lowercase (or sometimes things like camelCase). I suppose there might be some oddball lua runtime out there that is case-insensitive, but I don't know of one.
Type misuse.
Updated is a boolean (a true/false value), so the syntax:
while Change[true] do
...is invalid. See:
> if Updated[true] then
>> print("foo")
>> end
stdin:1: attempt to index global 'Updated' (a boolean value)
stack traceback:
stdin:1: in main chunk
[C]: in ?
Note also that the "While change == true do" is also wrong because of case ("While" is not valid lua, but "while" is).
Lastly:
Lack of threading.
You have basically two different things that you're trying to do at once, namely randomly change the "worth" variable as fast as possible (it's in a loop) and see a set a label to match it (it looks like you probably want it to change constantly). This requires two threads of operation (one to change worth and another to read it and stick it on the label). You've written this like you're assuming you have a spreadsheet or something and that. What your code is actually doing is:
Setting some variables
Updating worth indefinitely, printing 'Working!' a bunch, and...
Never stopping
The rest of the code never runs, because the rest of the code isn't in a background thread (basically the first bit monopolizes the runtime and never yields to everything else).
Lastly, even if the top code was running in the background, you only set the Text label one-time to exactly "Bitcoin is currently worth: 3456" (or some similar number) one time. The way this is written there won't be any updates thereafter (and, if it runs once before the other thread has warmed up, it might not be set to anything useful at all).
My guess is that your runtime is spitting out errors left and right due to the identifier problems and/or is running in a tight infinite loop and never actually getting to the label refresh logic.
BJ Black has given an excellent description of the issues with the syntax, so I'll try to cover the Roblox piece of this. In order for this kind of thing to work properly in a Roblox game, here are some assumptions to double check :
Since we are working with a TextLabel, is it inside a ScreenGui? Or a SurfaceGui?
If it's in a ScreenGui, make sure that ScreenGui is in StarterGui, and is this code in a LocalScript
If it's in a SurfaceGui, make sure that SurfaceGui is adorning a Part and this code
is in a Script
After you checked all those pieces, maybe this is closer to what you were thinking :
-- define the variables we're working with
local textLabel = script.Parent.TextLabel
local worth = 0
-- create an infinite loop
spawn(function()
while true do
--Pick random number
worth = math.random(1,4500)
-- update the text of the label with the new worth
textLabel.Text = string.format("Bitcoin is currently worth: %d", worth)
-- wait for 3 minutes, then loop
wait(180)
end
end)
I removed Updated and Changed because all they were doing was deciding whether or not to change the value. The flow of your loop was:
do nothing and display an undefined number. Wait 3 minutes
update the number, display it, wait 6 minutes
repeat 1 and 2.
So hopefully this is a little clearer and closer to what you were thinking.

FCEUX stops responding when i run this code made by me

--llama a IUP
require("iuplua")
--Variables
on= 1
puntos1=memory.readbyte(0x0007DE) --Read the points value
puntos2=memory.readbyte(0x0007DF)
puntos3=memory.readbyte(0x0007E0)
puntos4=memory.readbyte(0x0007E1)
puntos5=memory.readbyte(0x0007E2)
p1=puntos1*100000 --Convert the raw values to it's game value
p2=puntos2*10000
p3=puntos3*1000
p4=puntos4*100
p5=puntos5*10
maxpuntaje=p1+p2+p3+p4+p5 --Calculate the final result
mundo=memory.readbyte(0x00075F) --Read the "world" value
nivel=memory.readbyte(0x000760) --Read the "level" value
estado=memory.readbyte(0x000770) --Read the mario "state" (00 not in game, 01 playing, 03 game over)
--Escribir las variables anteriores al morir
memory.writebyte(0x00075A,00) --Change the "lives" value to 1
while(on==1) do
estado=memory.readbyte(0x000770)
print(estado)
print(type(estado))
if(estado==03)then
print("Puntuacion maxima (sesion actual) = ",maxpuntaje)
print("Mundo y nivel Actual: ",mundo+1,"-",nivel+1)
end
end
(code edited)
This is the state of 0x000770 when playing
This is the state of 0x000770 when the Game Over scene jumps in
is there anything wrong? fceux just stop responding when i run this script, im new at stacks overflow and at programming so, every help will be welcome
It's rather simple to debug this but more information is required
Make sure (estado==03) yields true and also print following variables and add into your question
mundo=memory.readbyte(0x00075F)
nivel=memory.readbyte(0x000760)
estado=memory.readbyte(0x000770)
print(mundo, nivel, estado)
Check the types of these memory read vaiables i-g print(type(mundo))
Make Sure that the if condition checks against correct types
You realize that memonry is read once and while is always true
Try this:
while(on==1) do
estado=memory.readbyte(0x000770)
print(estado)
print(type(estado))
if(estado==03)then
print("Puntuacion maxima (sesion actual) = ",maxpuntaje)
print("Mundo y nivel Actual: ",mundo+1,"-",nivel+1)
end
end
im so sorry for wasting your time, but i found the error, it was actually quite simple, there was a missing FCEU.frameadvance at the end of the cycle.
i dont know why it caused the emulator to crash but after putting it in place it stopped crashing. thanks to wsha for helping.

Lua - Couple Questions

Im a amatuer at coding. So, mind me if i face palmed some things.
Anyways, im making a alpha phase for a OS im making right? I'm making my installer. Two questions. Can i get a code off of pastebin then have my lua script download it? Two. I put the "print" part of the code in cmd. I get "Illegal characters". I dont know what went wrong. Here's my code.
--Variables
Yes = True
No = False
--Loading Screen
print ("1")
sleep(0.5)
print("2")
sleep(0.5)
print("Dowloading OS")
sleep(2)
print("Done!")
sleep(0.2)
print("Would you like to open the OS?")
end
I see a few issues with your code.
First of all, True and False are both meaningless names - which, unless you have assigned something to them earlier, are both equal to nil. Therefore, your Yes and No variables are both set to nil as well. This isn't because true and false don't exist in lua - they're just in lowercase: true and false. Creating Yes and No variables is redundant and hard to read - just use true and false directly.
Second of all, if you're using standard lua downloaded from their website, sleep is not a valid function (although it is in the Roblox version of Lua, or so I've heard). Like uppercase True and False, sleep is nil by default, so calling it won't work. Depending on what you're running this on, you'll want to use either os.execute("sleep " .. number_of_seconds) if you're on a mac, or os.execute("timeout /t " .. number_of_seconds) if you're on a PC. You might want to wrap these up into a function
function my_sleep_mac(number_of_seconds)
os.execute("sleep " .. number_of_seconds)
end
function my_sleep_PC(number_of_seconds)
os.execute("timeout /t " .. number_of_seconds)
end
As for the specific error you're experiencing, I think it's due to your end statement as the end of your program. end in lua doesn't do exactly what you think it does - it doesn't specify the end of the program. Lua can figure out where the program ends just by looking to see if there's any text left in the file. What it can't figure out without you saying it is where various sub-blocks of code end, IE the branches of if statements, functions, etc. For example, suppose you write the code
print("checking x...")
if x == 2 then
print("x is 2")
print("Isn't it awesome that x is 2?")
print("x was checked")
lua has no way of knowing whether or not that last statement, printing the x was checked, is supposed to only happen if x is 2 or always. Consequently, you need to explicitly say when various sections of code end, for which you use end. For a file, though, it's unnecessary and actually causes an error. Here's the if statement with an end introduced
print("checking x...")
if x == 2 then
print("x is 2")
print("isn't it awesome that x is 2?")
end
print("x was checked")
although lua doesn't care, it's a very good idea to indent these sections of code so that you can tell at a glance where it starts and ends:
print("checking x...")
if x == 2 then
print("x is 2")
print("isn't it awesome that x is 2?")
end
print("x was checked")
with regards to your "pastebin" problem, you're going to have to be more specific.
You can implement sleep in OS-independent (but CPU-intensive) way:
local function sleep(seconds)
local t0 = os.clock()
repeat
until os.clock() - t0 >= seconds
end

Evaluating a math string in Corona Lua

I would like to evaluate a math string in my corona app. Right now I'm focusing on the trig functions, so let's let the example be the most difficult we're likely to face:
local expr = "2sin(4pi+2)+7"
My goal is for this to somehow be (either) evaluated as is with maybe a pi --> math.pi switch, or to even break it up. The breaking up would be much more difficult, however, since it COULD be as complicated a above, but could also just be sin(1).
So I would prefer to stay as close to the python eval(expr) function as possible, but if that can't happen, I am flexible.
The simplest way would be to replace sin with math.sin (pi with math.pi and so on), add missing multiplications signs, and run it through loadstring, but loadstring is not available in Corona environment.
This means you will need to write your own parser for these expressions. I found a discussion on Corona forums that may help you as a starting point: here, with some details and a demo here
This should do the trick, it is able to use the lua math functions without putting 'math.function' so just sqrt(100) works fine. I threw this together because I have seen this question asked way too many times. Hopes this helps :)
If you have any questions feel free to contact me at rayaman99#gmail.com
function evaluate(cmd,v) -- this uses recursion to solve math equations
--[[ We break it into pieces and solve tiny pieces at a time then put them back together
Example of whats going on
Lets say we have "5+5+5+5+5"
First we get this:
5+5+5+5 + 5
5+5+5 + 5
5+5 + 5
5 + 5
Take all the single 5's and do their opperation which is addition in this case and get 25 as our answer
if you want to visually see this with a custom expression, uncomment the code below that says '--print(l,o,r)'
]]
v=v or 0
local count=0
local function helper(o,v,r)-- a local helper function to speed things up and keep the code smaller
if type(v)=="string" then
if v:find("%D") then
v=tonumber(math[v]) or tonumber(_G[v]) -- This section allows global variables and variables from math to be used feel free to add your own enviroments
end
end
if type(r)=="string" then
if r:find("%D") then
r=tonumber(math[r]) or tonumber(_G[r]) -- A mirror from above but this affects the other side of the equation
-- Think about it as '5+a' and 'a+5' This mirror allows me to tackle both sides of the expression
end
end
local r=tonumber(r) or 0
if o=="+" then -- where we handle different math opperators
return r+v
elseif o=="-" then
return r-v
elseif o=="/" then
return r/v
elseif o=="*" then
return r*v
elseif o=="^" then
return r^v
end
end
for i,v in pairs(math) do
cmd=cmd:gsub(i.."(%b())",function(a)
a=a:sub(2,-2)
if a:sub(1,1)=="-" then
a="0"..a
end
return v(evaluate(a))
end)
end
cmd=cmd:gsub("%b()",function(a)
return evaluate(a:sub(2,-2))
end)
for l,o,r in cmd:gmatch("(.*)([%+%^%-%*/])(.*)") do -- iteration this breaks the expression into managable parts, when adding pieces into
--print(":",l,o,r) -- uncomment this to see how it does its thing
count=count+1 -- keep track for certain conditions
if l:find("[%+%^%-%*/]") then -- if I find that the lefthand side of the expression contains lets keep breaking it apart
v=helper(o,r,evaluate(l,v))-- evaluate again and do the helper function
else
if count==1 then
v=helper(o,r,l) -- Case where an expression contains one mathematical opperator
end
end
end
if count==0 then return (tonumber(cmd) or tonumber(math[cmd]) or tonumber(_G[cmd])) end
-- you can add your own enviroments as well... I use math and _G
return v
end
a=5
print(evaluate("2+2+2*2")) -- This still has work when it comes to pemdas; however, the use parentheses can order things!
print(evaluate("2+2+(2*2)"))-- <-- As seen here
print(evaluate("sqrt(100)"))
print(evaluate("sqrt(100)+abs(-100)"))
print(evaluate("sqrt(100+44)"))
print(evaluate("sqrt(100+44)/2"))
print(evaluate("5^2"))
print(evaluate("a")) -- that we stored above
print(evaluate("pi")) -- math.pi
print(evaluate("pi*2")) -- math.pi

Resources