Invocation of synced command outside of the players turn

Discussion of Lua and LuaWML support, development, and ideas.

Moderator: Forum Moderators

Post Reply
Tonk
Posts: 5
Joined: April 15th, 2020, 8:08 am

Invocation of synced command outside of the players turn

Post by Tonk »

Hi,

I've working on a mod that's allows it's players to place down different marks on the battleground's tiles.
The KEY FEATURE would be to any player at any time could place any marker at any tile trough the context menu. I'm trying to achieve similar behaviour to the built in Set Label or Clear Labels, just with icons instead of text. Is it possible to implement such feature with lua?
Since the mod doesn't effect any important in game values the OOS aspect is irrelevant.

This is what I've been tried so far (unfortunately not working, player can't use It outside of It's turn):

Code: Select all

--- ping.cfg ---

[event]
    name=prestart

    [set_menu_item]
        id=ping_place_marker
        description="Place a Mark"
        synced = no

        [command]
            [lua]
            	[args]
                	x=$x1
                	y=$y1
            	[/args]
                code= <<
                        local marker = wml.variables["ping_selected_marker"]
                        local team = wml.variables["ping_team"]
                        local args = ...;
                        local ping = wesnoth.require("~add-ons/Ping/lua/ping.lua")
                        ping.place_marker_at(args.x, args.y,team, marker)
                    >>
            [/lua]
        [/command]
    [/set_menu_item]
[/event]


--- ping.lua ---

res = {}

function res.place_marker_at(x,y, team, marker)
    wesnoth.sync.invoke_command("synced_place_marker_at", {
        x = x, 
        y = y,
        team = team, 
        marker = marker
    })
end

function get_marker(id)
    local img
    if id == 0 then
        img  ="/mark-danger.png"
    elseif id == 1 then
        img = "/mark-here.png"
    elseif id == 2 then
        img = "/mark-protect.png"
    elseif id == 3 then
        img = "/mark-target.png"
    else
        img = "/icons/none.png"
    end
    return "marks" .. img
end

wesnoth.custom_synced_commands.synced_place_marker_at = function(cfg)
    local visible = wml.variables["ping_is_visible"] or false
    if visible then
        wml.fire.item({
            x = cfg.x, 
            y = cfg.y,
            team_name = cfg.team,
            visible_in_fog = true,
            image = get_marker(cfg.marker),
            name = "ping_mark"
        })
    end

    local length = wml.variables["ping_marks.length"] or 0
    wml.variables["ping_marks[".. length .."].x"] = cfg.x
    wml.variables["ping_marks[".. length .."].y"] = cfg.y
    wml.variables["ping_marks[".. length .."].team"] = cfg.team
    wml.variables["ping_marks[".. length .."].marker"] = cfg.marker
end

return res
Thanks in advance for any suggestion.
Last edited by Tonk on December 16th, 2024, 2:18 pm, edited 2 times in total.
User avatar
Celtic_Minstrel
Developer
Posts: 2371
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Invocation of synced command outside of the players turn

Post by Celtic_Minstrel »

I'm not sure if there's even a way to put the item in the menu outside of a player's turn. Maybe synced=no in the [set_menu_item] could do it? But even if it does, that has undesirable side-effects for what you're doing.

And even if you can get the menu item to be invoked outside of the player's turn, I suspect you wouldn't be able to invoke the synced command outside of their turn.

By the way, your [args] tag is misplaced there. It should go inside the [lua] tag.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
Tonk
Posts: 5
Joined: April 15th, 2020, 8:08 am

Re: Invocation of synced command outside of the players turn

Post by Tonk »

Thanks for the pointing out some type-o, I've corrected it now. (I have made some mistake while creating this post).
Unfortunately synced=no is not solving my problem, It let the player to fire the command but has no effect when it is fired outside of the player's turn.
User avatar
Celtic_Minstrel
Developer
Posts: 2371
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Invocation of synced command outside of the players turn

Post by Celtic_Minstrel »

Since it turns out that it does let them fire it outside their turn, then you can probably somehow get it to work, though it might be quite tricky. I'm not sure if there's a way to directly fire a synced event when it's not your turn, but even if that's not possible (which seems likely), you should be able to "fake" it to a degree. Queuing up changes and sending them all when the player's turn starts should be viable, for example. But of course, that means other players won't see the changes immediately, so I'm not sure that actually helps you in the end.

There is definitely a system for out-of-turn actions, which I assume is really what you're looking for. At minimum chat messages fall into that, and possibly labels. But I'm not sure if there's anything that exposes this system to WML and Lua. I don't think labels or chat messages are treated as synched events.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
Post Reply