LUA script help please. [Solved]

Place to get help with not working mods / modding interface.
User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

LUA script help please. [Solved]

Post by bobingabout »

Despite the vast evidence that I'm good at LUA, I'm not the best when it comes to knowing LUA script.

I have a GUI object named button#, where # is an unknown number that I Want to find.

First I did this:

Code: Select all

      for i=1,49 do
        if event.element.name == "button" .. i then
--other code here
        end
      end
And although it worked, I thought it was dumb.

so I did this:

Code: Select all

      i = tonumber(string.sub(event.element.name, string.find(event.element.name, "%d+")))
--other code here
And although that works too, there's a function call (find the start and end bytes of the number) in a function call (extract those bytes of data as a string) in a function call (convert that string to a number)... I don't like it either.



Does anyone have any ideas for a better way of doing it?
Last edited by bobingabout on Sun Nov 20, 2016 12:53 am, edited 1 time in total.
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.
User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5412
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: LUA script help please.

Post by Klonan »

bobingabout wrote: so I did this:

Code: Select all

      i = tonumber(string.sub(event.element.name, string.find(event.element.name, "%d+")))
--other code here
And although that works too, there's a function call (find the start and end bytes of the number) in a function call (extract those bytes of data as a string) in a function call (convert that string to a number)... I don't like it either.

Does anyone have any ideas for a better way of doing it?
You can simplify this a little but, but personally i don't mind the iterating method

Code: Select all

local string = event.element.name
local i = string:gsub("button", "")
--other code here
The 'tonumber' isn't strictly necessary, as if you do anything with it, it will be interpreted correctly as a number - even though type() says it is a string
User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: LUA script help please.

Post by bobingabout »

Klonan wrote:The 'tonumber' isn't strictly necessary, as if you do anything with it, it will be interpreted correctly as a number - even though type() says it is a string
In my case it is required, because the number is used as an index in a table. If I use the string directly, it returns nil, but if I tonumber it first, it returns the value.
I did actually try this without the tonumber, that's why I know it doesn't work without it.

Thanks for your advice.

new code:

Code: Select all

      local string = event.element.name
      local s = string:gsub("button", "")
      local i = tonumber(s)
-- other code here
It does look better, I'll change it and try it now.
Last edited by bobingabout on Sun Nov 20, 2016 12:09 am, edited 1 time in total.
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.
User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5412
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: LUA script help please.

Post by Klonan »

bobingabout wrote:
Klonan wrote:The 'tonumber' isn't strictly necessary, as if you do anything with it, it will be interpreted correctly as a number - even though type() says it is a string
In my case it is required, because the number is used as an index in a table. If I use the string directly, it returns nil, but if I tonumber it first, it returns the value.
I did actually try this without the tonumber, that's why I know it doesn't work without it.

Thanks for your advice.
While i'm not sure which is more efficient, you can just add 0 to the result, instead of calling tonumber()

In the end it will make practically no difference
Choumiko
Smart Inserter
Smart Inserter
Posts: 1352
Joined: Fri Mar 21, 2014 10:51 pm
Contact:

Re: LUA script help please.

Post by Choumiko »

Code: Select all

i = tonumber(string.match(event.element.name, "%d+$"))
This should take only numbers from the end of the string, just in case at some point you want something like 1button2 :)
User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: LUA script help please.

Post by bobingabout »

Choumiko wrote:

Code: Select all

i = tonumber(string.match(event.element.name, "%d+$"))
This should take only numbers from the end of the string, just in case at some point you want something like 1button2 :)
Good advice, and although it does work, for some reason I decided to use Klonan's solution. Maybe it's the intimidating face in his huge avatar, or perhaps the pink name.

Okay, after a little tinkering, I've decided on the following.

Code: Select all

      local i = string.gsub(event.element.name, "button", "") + 0
--other code here
Thanks for the help guys.
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.
User avatar
Mooncat
Smart Inserter
Smart Inserter
Posts: 1210
Joined: Wed May 18, 2016 4:55 pm
Contact:

Re: LUA script help please. [Solved]

Post by Mooncat »

One thing to note: if you want to use on_gui_click, which is very likely you would, you may need to consider adding prefix to your button names.

Having generic names like "button0" is not safe. If there is another mod using the same button name, clicking its button will also trigger on_gui_click with the same name on your mod.
That's why I added "creative-mode_" prefix in all my GUI elements, as well as items, entities, etc.

But if you use hyphen (-), you will need to escape it with % when used as pattern in string.sub, string.gsub, string.find, string.match, etc. i.e. it will be "creative%-mode_"
User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: LUA script help please. [Solved]

Post by bobingabout »

Mooncat wrote:One thing to note: if you want to use on_gui_click, which is very likely you would, you may need to consider adding prefix to your button names.

Having generic names like "button0" is not safe. If there is another mod using the same button name, clicking its button will also trigger on_gui_click with the same name on your mod.
That's why I added "creative-mode_" prefix in all my GUI elements, as well as items, entities, etc.

But if you use hyphen (-), you will need to escape it with % when used as pattern in string.sub, string.gsub, string.find, string.match, etc. i.e. it will be "creative%-mode_"
I have already thought of this. I actually have 3 sets of buttons, two named button1 to button49, and one of only 1 to 9. The clicked check is in two phases, first to check the name of the button that was pressed, to see if it starts with "button", and the second check checks the name of the parent. Although the button itself doesn't have a prefix, the parent does.

So... you have actually given me something to think about here, perhaps I should prefix those buttons too, with something like "bob_inserters_"
Note, I use underscores not dashes, so I can actually reference it such as gui.bob_inserters_pickup.button1.state if I want to. Works with underscores, not with dashes.
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.
User avatar
Mooncat
Smart Inserter
Smart Inserter
Posts: 1210
Joined: Wed May 18, 2016 4:55 pm
Contact:

Re: LUA script help please. [Solved]

Post by Mooncat »

bobingabout wrote:
Mooncat wrote:One thing to note: if you want to use on_gui_click, which is very likely you would, you may need to consider adding prefix to your button names.

Having generic names like "button0" is not safe. If there is another mod using the same button name, clicking its button will also trigger on_gui_click with the same name on your mod.
That's why I added "creative-mode_" prefix in all my GUI elements, as well as items, entities, etc.

But if you use hyphen (-), you will need to escape it with % when used as pattern in string.sub, string.gsub, string.find, string.match, etc. i.e. it will be "creative%-mode_"
I have already thought of this. I actually have 3 sets of buttons, two named button1 to button49, and one of only 1 to 9. The clicked check is in two phases, first to check the name of the button that was pressed, to see if it starts with "button", and the second check checks the name of the parent. Although the button itself doesn't have a prefix, the parent does.

So... you have actually given me something to think about here, perhaps I should prefix those buttons too, with something like "bob_inserters_"
Note, I use underscores not dashes, so I can actually reference it such as gui.bob_inserters_pickup.button1.state if I want to. Works with underscores, not with dashes.
Yes, checking on parent element first works too! In fact, I also do it in my mod. ;)
Because I think using string patterns is slower than straightforward string comparison. Not tested though.
(But I believe the difference is negligible. It is on-click event, it isn't supposed to run very frequently anyway. Just a (bad) habit. :lol: )

But keeping the child button name to be generic may still cause problems if someone thought on_gui_click is only called for the elements from his mod so "button0" always refer to his button, and he does something like

Code: Select all

if button.name == "button0" then
  button.destroy()
end
Just play safe. :lol:
Post Reply

Return to “Modding help”