Lua only fire on local client
Moderator: Forum Moderators
Lua only fire on local client
I'm making a menu item that plays a track and I want it to only apply to the client that selected it.
So far I have this
how do I make the LUA code only apply to the local client?
So far I have this
Code: Select all
[set_menu_item]
id=playlist_menu
image=icons/music_icon.png
description= _ "Select a Playlist"
[command]
[message]
speaker=narrator
side_for=$side_number
[option]
message={MENU_IMG_TXT "icons/music_icon.png" "Crock Test 1"}
[command]
[lua]
code=<<
wesnoth.fire("music", { name="crock_-_optic_deception.ogg", play_once="yes", immediate="yes" })
>>
[/lua]
[/command]
[/option]
[/message]
[/command]
[/set_menu_item]
- Elvish_Hunter
- Posts: 1575
- Joined: September 4th, 2009, 2:39 pm
- Location: Lintanir Forest...
Re: Lua only fire on local client
Usually UMC authors should seek exactly the opposite, that is having everything correctly synchronized, otherwise OOS errors may occur.Azeal wrote:how do I make the LUA code only apply to the local client?
That said, the first thing to try is using an unsafe multiplayer event. Here you can find a list of MP safe events, so you'll need one that isn't on this list: the prestart or start event should do.
The second thing that I'd try will be (at least for testing purposes) avoiding the [set_menu_item] thing, and place the [message] block directly inside the event. This way, you'll have one less thing to worry about for now. Also, [set_menu_item] can be used to force syncronization (with the option needs_select=yes), so if you want to use it you'll need to create a custom Lua dialog to invoke instead of [message], as Lua dialogs are MP-unsafe if wesnoth.synchronize_choice() is not used.
The third thing is not related to synchronization, but about your Lua command. Instead of relying on wesnoth.fire (outdated practice), you can just call directly the corresponding Lua function, that is wesnoth.set_music():
Code: Select all
wesnoth.set_music { name="crock_-_optic_deception.ogg", play_once="yes", immediate="yes" }
Current maintainer of these add-ons, all on 1.16:
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
Re: Lua only fire on local client
Well, those events will still get triggered on every client, so they won't do. Them not being MP safe merely means that if you use the RNG or present [option]s in a prestart/start event, the results/choices won't be synchronized. In case of [option]s, I think the other clients would simply pick the first option.Elvish_Hunter wrote:That said, the first thing to try is using an unsafe multiplayer event. Here you can find a list of MP safe events, so you'll need one that isn't on this list: the prestart or start event should do.
I don't think there's a workaround using start events and [option]s which would allow you to do what he wants to do, at least not for more than two players.
-
- Inactive Developer
- Posts: 2461
- Joined: August 15th, 2008, 8:46 pm
- Location: Germany
Re: Lua only fire on local client
First, let's distinguish between local and active client.
There always is exactly one side in this strictly turn based game which can currently move and call [set_menu_item]s, which is the side of the currently active client. All other sides cannot do either of these during that.
So, what you can do (I think) is make this music play only on the currently active client, namely by putting that code into
a function which you pass to wesnoth.synchronize_choice. Look up its documentation. Note that this is sort of a hack, as it's using that function not quite for what it is intended for. I'm also doing it in SoW anyway.
EDIT
So, it should be usable for solving the problem. The wesnoth.sync_choice method is cleaner however, and it would not make much sense to the player why he needs to select a unit in order to trigger music.
There always is exactly one side in this strictly turn based game which can currently move and call [set_menu_item]s, which is the side of the currently active client. All other sides cannot do either of these during that.
So, what you can do (I think) is make this music play only on the currently active client, namely by putting that code into
a function which you pass to wesnoth.synchronize_choice. Look up its documentation. Note that this is sort of a hack, as it's using that function not quite for what it is intended for. I'm also doing it in SoW anyway.
EDIT
IIRC you suggested in another thread which I recall to use the name=select event to create out-of-sync variables. That event actually is triggered only on the active (not local, I think, but needs a test) client.zookeeper wrote:Well, those events will still get triggered on every client, so they won't do. Them not being MP safe merely means that if you use the RNG or present [option]s in a prestart/start event, the results/choices won't be synchronized.
So, it should be usable for solving the problem. The wesnoth.sync_choice method is cleaner however, and it would not make much sense to the player why he needs to select a unit in order to trigger music.
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml starters • Plan Your Advancements: mp mod
The Earth's Gut: sp campaign • Settlers of Wesnoth: mp scenario • Wesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
A Simple Campaign: campaign draft for wml starters • Plan Your Advancements: mp mod
The Earth's Gut: sp campaign • Settlers of Wesnoth: mp scenario • Wesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
Re: Lua only fire on local client
I've solved this (for now) using a select event. The set_menu_item is wrapped in it and it generates an id that includes $side_number (thanks to zookeeper), so you don't need to select a unit to fire the music, just to create the menu item. Also this does cause an OOS message. I've had a look through the Lua documentation particularly the syncronize_choice but I'm having a hard time grasping it. From what I gather on the wiki page syncronize_choice is used to recover WML that was executed on a single client, and then sync it to other clients (at least the example code).
Another problem is that any work around will probably cause an OOS message, that while is harmless, may be annoying. Is there anyway to make it so a client will ignore the OOS and not pop up with a message?
can a Lua dialog contain options and commands? If so wouldn't using Lua dialog instead of messages achieve the result I'm looking for (cause the command to only execute on a single client)?Elvish_Hunter wrote:Lua dialog to invoke instead of [message], as Lua dialogs are MP-unsafe if wesnoth.synchronize_choice() is not used.
Another problem is that any work around will probably cause an OOS message, that while is harmless, may be annoying. Is there anyway to make it so a client will ignore the OOS and not pop up with a message?
-
- Inactive Developer
- Posts: 2461
- Joined: August 15th, 2008, 8:46 pm
- Location: Germany
Re: Lua only fire on local client
Yes. The point is that the code passed to sync_choice in form of a function is executed only on the active client, which is what you want. The result could then be passed to the other clients, but your use case doesn't need that. The wml can remain unchanged, though IIRC the side_for= key in [message] is ignored in case that that message has an [option]. Such messages can only be shown on the currently active client. Here's the lua part from above modified accordingly. (untested):Azeal wrote:I've had a look through the Lua documentation particularly the syncronize_choice but I'm having a hard time grasping it. From what I gather on the wiki page syncronize_choice is used to recover WML that was executed on a single client, and then sync it to other clients (at least the example code).
Code: Select all
code= <<
local foo = function()
wesnoth.fire("music", { name="crock_-_optic_deception.ogg", play_once="yes", immediate="yes" })
end
wesnoth.synchronize_choice(foo)
>>
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml starters • Plan Your Advancements: mp mod
The Earth's Gut: sp campaign • Settlers of Wesnoth: mp scenario • Wesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
A Simple Campaign: campaign draft for wml starters • Plan Your Advancements: mp mod
The Earth's Gut: sp campaign • Settlers of Wesnoth: mp scenario • Wesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
- Pentarctagon
- Project Manager
- Posts: 5564
- Joined: March 22nd, 2009, 10:50 pm
- Location: Earth (occasionally)
Re: Lua only fire on local client
This is working code that I have from this thread:
Code: Select all
[lua]
code=<<
local function foo()
local has_file = false
wesnoth.fire("music", { name="$music_text", append="$music_append", play_once="$music_once", immediate="yes" })
return { has_file = has_file }
end
local has_file = wesnoth.synchronize_choice(foo).has_file
>>
[/lua]
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
take one down, patch it around
-2,147,483,648 little bugs in the code
Re: Lua only fire on local client
works perfectly, thank you very much!Anonymissimus wrote:Yes. The point is that the code passed to sync_choice in form of a function is executed only on the active client, which is what you want. The result could then be passed to the other clients, but your use case doesn't need that. The wml can remain unchanged, though IIRC the side_for= key in [message] is ignored in case that that message has an [option]. Such messages can only be shown on the currently active client. Here's the lua part from above modified accordingly. (untested):Azeal wrote:I've had a look through the Lua documentation particularly the syncronize_choice but I'm having a hard time grasping it. From what I gather on the wiki page syncronize_choice is used to recover WML that was executed on a single client, and then sync it to other clients (at least the example code).Code: Select all
code= << local foo = function() wesnoth.fire("music", { name="crock_-_optic_deception.ogg", play_once="yes", immediate="yes" }) end wesnoth.synchronize_choice(foo) >>