Probably stupid lua question
Moderator: Forum Moderators
- Spannerbag
- Posts: 759
- Joined: December 18th, 2016, 6:14 pm
- Location: Yes
Probably stupid lua question
Hi,
I'm trying to make a version of
The first unit in the list that exists on the map issues the message then the routine quits.
If no unit is found it does nothing (like normal
Ideally in time I'd like to generalise this to accept a
If there's some way to do this within
Here's what I have:
Path is correct.
WML:
The first and last ids exist (are on the map), the middle one does not.
The two normal
lua:
No errors on screen or in logs.
lua console (last few lines for brevity):
Even if I just specify a single id (SMtest) it does nothing.
I guess that the logic isn't finding any units despite the first and last existing on-map.
I don't know lua that well and in the absence of error messages am out of my depth.
Could someone point out what I'm doing wrong please (I'm sure it'll be something stupid)?
Thanks in advance.
Cheers!
-- Spannerbag
I'm trying to make a version of
[message]
that can accept a list of unit id
s to simplify (remove) WML to winnow down choices.The first unit in the list that exists on the map issues the message then the routine quits.
If no unit is found it does nothing (like normal
[message]
).Ideally in time I'd like to generalise this to accept a
[filter]
(that can return more than one unit).If there's some way to do this within
[message]
please let me know because I tried (despite the wiki!) specifying multiple ids and it didn't work.Here's what I have:
_main.cfg
Code: Select all
[lua]
code="wesnoth.require '~add-ons/stub18/lua/msglist.lua'"
[/lua]
WML:
Code: Select all
[message]
speaker=SMtest
message=_"SMtest sanity test, next message has 2 ids"
[/message]
[message] # This does not work (didn't expect it to)
speaker=Goody,SMtest
message=_"This message has 2 ids"
[/message]
[msglist]
message=_"msglist test message!"
id=SMtest,notfound,Goody
[/msglist]
[message]
speaker=SMtest
message=_"Done msglist"
[/message]
The two normal
[message]
s work fine.lua:
Code: Select all
-- [msglist]
-- message=_"translatable string"
-- id=id1,id2,...
function wesnoth.wml_actions.msglist(cfg)
local msg = cfg.message or wml.error "[msglist] missing required message= attribute."
local msgids = cfg.id or wml.error "[msglist] missing required id= attribute."
for index, msgid in ipairs(msgids) do
local thisid=wesnoth.units.find_on_map{id=msgid}
if thisid ~= nil then
wml.fire.message{speaker=thisid,message=msg} end
end
end
lua console (last few lines for brevity):
Code: Select all
...
Running preload scripts...
$
wesnoth.dofile 'lua/wml-tags.lua'
wesnoth.dofile 'lua/feeding.lua'
wesnoth.dofile 'lua/diversion.lua'
wesnoth.dofile 'lua/stun.lua'
$ wesnoth.require '~add-ons/stub18/lua/dbck.lua'
$ wesnoth.require '~add-ons/stub18/lua/gold_min.lua'
$ wesnoth.require '~add-ons/stub18/lua/bannermsg.lua'
$ wesnoth.require '~add-ons/stub18/lua/msglist.lua'
I guess that the logic isn't finding any units despite the first and last existing on-map.
I don't know lua that well and in the absence of error messages am out of my depth.
Could someone point out what I'm doing wrong please (I'm sure it'll be something stupid)?
Thanks in advance.
Cheers!
-- Spannerbag
-
- Posts: 1456
- Joined: August 26th, 2018, 11:46 pm
- Location: A country place, far outside the Wire
Re: Probably stupid lua question
Pretty sure you can do this in wml (why?). According to https://wiki.wesnoth.org/InterfaceActio ... message.5D [message] takes a standard unit filter, so how about using foo,bar instead of speaker=foo,bar ?
As for lua, wesnoth.units.find_on_map returns an array, so you probably just need to use wesnoth.units.find_on_map{id=msgid}[1].
I'm not sure what you're passing as msgids, but it's possible you want msgid.id instead of msgid.
I'd probably add something like
wesnoth.interface.add_chat_message(string.format("%d\t%s",index,type(msgid))
right inside your for loop so you can see what you're working with. You might need to run wesnoth with --log-debug=scripting/lua for that, I don't remember because I just always do.
Also, you're passing a list, not an array. Unless some sort of automagic conversion goes on that I don't know about, I can't see how ipairs will work here. Hint:
I don't think it matters here, but it seems you're using require when you should be using dofile. Maybe someone else can help us both understand if that matters.
As for lua, wesnoth.units.find_on_map returns an array, so you probably just need to use wesnoth.units.find_on_map{id=msgid}[1].
I'm not sure what you're passing as msgids, but it's possible you want msgid.id instead of msgid.
I'd probably add something like
wesnoth.interface.add_chat_message(string.format("%d\t%s",index,type(msgid))
right inside your for loop so you can see what you're working with. You might need to run wesnoth with --log-debug=scripting/lua for that, I don't remember because I just always do.
Also, you're passing a list, not an array. Unless some sort of automagic conversion goes on that I don't know about, I can't see how ipairs will work here. Hint:
Code: Select all
for msgid in string.gmatch(msgids,"[%w]+") do
print(msgid)
end
Last edited by white_haired_uncle on June 9th, 2024, 12:53 pm, edited 1 time in total.
Speak softly, and carry Doombringer.
Re: Probably stupid lua question
https://wiki.wesnoth.org/LuaAPI/stringx#Functions is useful if you want to implement splitting. But as last post says, [message] already does most of what you need. Difference would be about priority of units, in that case you would need custom implementation.
With priority I would implement it like
With priority I would implement it like
Code: Select all
local old = wesnoth.wml_actions.message
function wesnoth.wml_actions.message(cfg)
if cfg.id ~= nil then
for index, msgid in ipairs(stringx.split(cfg.id)) do
local thisid=wesnoth.units.find_on_map{id=msgid}
if thisid ~= nil then
cfg.id=thisid.id
return old(cfg)
end
end
else
return old(cfg)
end
end
- Celtic_Minstrel
- Developer
- Posts: 2371
- Joined: August 3rd, 2012, 11:26 pm
- Location: Canada
- Contact:
Re: Probably stupid lua question
Or use wesnoth.units.get(msgid).white_haired_uncle wrote: ↑June 9th, 2024, 12:30 pm As for lua, wesnoth.units.find_on_map returns an array, so you probably just need to use wesnoth.units.find_on_map{id=msgid}[1].
He's passing a string. If the loop does anything at all, it's probably going to loop over the string one character at a time.white_haired_uncle wrote: ↑June 9th, 2024, 12:30 pm Also, you're passing a list, not an array. Unless some sort of automagic conversion goes on that I don't know about, I can't see how ipairs will work here.
They do essentially the same thing, but require caches the loaded module somewhere so that a subsequent call just returns the cache without loading it again. Also, if I recall correctly, require doesn't support passing arguments in to the loaded function.white_haired_uncle wrote: ↑June 9th, 2024, 12:30 pm I don't think it matters here, but it seems you're using require when you should be using dofile. Maybe someone else can help us both understand if that matters.
- Spannerbag
- Posts: 759
- Joined: December 18th, 2016, 6:14 pm
- Location: Yes
Re: Probably stupid lua question
Thanks for all your help, much appreciated.
Y'know I'm going (more) crazy; I thought I'd tested
However tried again just now... and it worked.
I much prefer working in WML if possible so I'll stick with
I'll see how I get on using
However I'll keep the lua in back pocket just in case.
Sorry for wasting your time - I really thought I'd tested
Many thanks for your time and trouble.
Cheers!
-- Spannerbag
Y'know I'm going (more) crazy; I thought I'd tested
id=id1,id2...
in [message]
and thought it failed.However tried again just now... and it worked.

I much prefer working in WML if possible so I'll stick with
[message]
with multiple ids for now.I'll see how I get on using
[message]
's filtering as well.However I'll keep the lua in back pocket just in case.

Sorry for wasting your time - I really thought I'd tested
id=
!Many thanks for your time and trouble.
Cheers!
-- Spannerbag