vultraz's lua questions

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

Moderator: Forum Moderators

Post Reply
User avatar
vultraz
Developer
Posts: 960
Joined: February 7th, 2011, 12:51 pm
Location: Dodging Daleks

Re: vultraz's lua questions

Post by vultraz »

Elvish_Hunter wrote:So, vultraz, I tested on a small toggle panel. My conclusion is that it does not support selecting more than one item at the same time, sorry.
Hum....well....the example you have is basicaly what I have, but mine's within a [listbox][toggle_panal]. Does that mean that the multiple checkbox selected thingy won't work if within a listbox/toggle_panal?
Creator of Shadows of Deception (for 1.12) and co-creator of the Era of Chaos (for 1.12/1.13).
SurvivalXtreme rocks!!!
What happens when you get scared half to death...twice?
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: vultraz's lua questions

Post by Elvish_Hunter »

vultraz wrote:Does that mean that the multiple checkbox selected thingy won't work if within a listbox/toggle_panal?
Exactly. For this reason I went for a different solution that does not involve listboxes at all. In fact, our listboxes are what in other GUIs are known as radiobuttons.
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)
User avatar
vultraz
Developer
Posts: 960
Joined: February 7th, 2011, 12:51 pm
Location: Dodging Daleks

Re: vultraz's lua questions

Post by vultraz »

HUmm..interesting. So I either get rid of the multiple selection stuff or use your system. Might be able to think of a way to combine both.... hummmm :P

OH BTW, as for the thing about events firing in the victory event. I remember I got it to fire a few times (from the victory event) before during the early coding stages of that function. I think it must be something with the function, not the victory event structure, because the event won't fire even in a 'side 1 turn 1' event. :hmm:
Creator of Shadows of Deception (for 1.12) and co-creator of the Era of Chaos (for 1.12/1.13).
SurvivalXtreme rocks!!!
What happens when you get scared half to death...twice?
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: vultraz's lua questions

Post by Anonymissimus »

Elvish_Hunter wrote:I also found a bug (at least I suppose that it is one; I need to create a testcase and report it), that closes the campaign when a toggle_panel without an image widget is used:

Code: Select all

Image does not fit the canvas.

Condition 'static_cast<int>(h) >= 0' failed at src/gui/auxiliary/canvas.cpp:1079 in function 'draw'. Extra development information: Image 'misc/selection2-border-left.png', h = -3.
Not sure about the usefulness of gui2 lua dialog bug reports. Not only is the one to fix it already overfreighted with bugs assigned to him, but also still quite annoyed about his gui toolkit being exposed in the lua interface without him ever having been asked about it. ^_^
Perhaps creating a grid = {} and using table.insert() to add all the rows you may be able to obtain what you want - but I cannot guarantee anything.
The side selection in SoW works that way yes, and it adapts dynamically to the number of sides there are. (multiple selection is no problem) It's using gui2 in a way it's not supposed to be used however according to shadowmaster (Constructing dialog content dynamically; the ones in the engine which do that are all still gui1.).
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml startersPlan Your Advancements: mp mod
The Earth's Gut: sp campaignSettlers of Wesnoth: mp scenarioWesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: vultraz's lua questions

Post by Elvish_Hunter »

vultraz wrote:OH BTW, as for the thing about events firing in the victory event. I remember I got it to fire a few times (from the victory event) before during the early coding stages of that function. I think it must be something with the function, not the victory event structure, because the event won't fire even in a 'side 1 turn 1' event. :hmm:
Can you post the code of the herodevel event, so I can take a look?
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)
User avatar
vultraz
Developer
Posts: 960
Joined: February 7th, 2011, 12:51 pm
Location: Dodging Daleks

Re: vultraz's lua questions

Post by vultraz »

Here's the whole file:

Also, do you have any idea how a [multi_page] widget works? I might ned it with these new updates to my inventory or the different lists of items (no listbox to be used).
Attachments
herodevel.cfg
(33.19 KiB) Downloaded 625 times
Creator of Shadows of Deception (for 1.12) and co-creator of the Era of Chaos (for 1.12/1.13).
SurvivalXtreme rocks!!!
What happens when you get scared half to death...twice?
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: vultraz's lua questions

Post by Elvish_Hunter »

HAHA! Victory is mine! :D :mrgreen:
I managed to press in service toggle buttons inside toggle panels; at this point, the postshow function can read the status of each checkbox!
Here there is the code that I'm using and a screenshot that proves that it's working.
Spoiler:
toggle_panel_plus_checkbuttons.png
toggle_panel_plus_checkbuttons.png (181.98 KiB) Viewed 5906 times
vultraz wrote:Here's the whole file:
I noticed that your herodevel event is coded this way:

Code: Select all

    [event]
        name=herodevel

        [store_unit]
             # blah
In this condition, herodevel can fire only once per scenario. I think that you should add first_time_only=no. I haven't tested, however, because I spent a lot of time on GUI stuff, as you can imagine...
vultraz wrote:Also, do you have any idea how a [multi_page] widget works?
Unfortunately, not. And mainline isn't helping me that much, because all our standard windows have only a [page_definition] inside [multi_page], but they don't have a [page_data], so it'll take me quite a lot of time to understand how multi_page works, and how to change pages, without even being sure that I'll be able to understand it, due to the scarce documentation. :(
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)
User avatar
vultraz
Developer
Posts: 960
Joined: February 7th, 2011, 12:51 pm
Location: Dodging Daleks

Re: vultraz's lua questions

Post by vultraz »

Elvish_Hunter wrote:HAHA! Victory is mine! :D :mrgreen:
I managed to press in service toggle buttons inside toggle panels; at this point, the postshow function can read the status of each checkbox!
Nice! :D Though I'm not sure how to maniulate the print() in the postshow's resulting values. I mean, where do the values go, how do I use them, etc. :P
Elvish_Hunter wrote:I noticed that your herodevel event is coded this way:
Hum..I'll try that.

EDIT3: well, I added first_time_only=no and now the event doesn't work at all. :augh:

Code: Select all

#define HERODEVEL_BASE
    [event]
        name=herodevel
        first_time_only=no

        [store_unit]
Elvish_Hunter wrote:Unfortunately, not. And mainline isn't helping me that much, because all our standard windows have only a [page_definition] inside [multi_page], but they don't have a [page_data], so it'll take me quite a lot of time to understand how multi_page works, and how to change pages, without even being sure that I'll be able to understand it, due to the scarce documentation
I left a question about that for mordante on IRC. Waiting for a response.

EDIT: Another question: If I stick the listbox in a multipage, how do I generate the pages and set the listbox values at the same time? Actually, how would I generate pages. I guess you would have to set the date defined in [page_definition], but that data happens to be the listbox, and ITS data, so how would I do that, if you understand what I'm saying?

EDIT2: ANNNND yet another question. A couple posts up I asked about that event not firing. Well, I got it to fire, BUT after the SECOND time I picked up the item. (I could pick it up a second time because the event removing it didn't fire the first time.) Related to that, I have a piece of code that checks whether the player has an item of the same type already, and if they do, just add 1 to the quantity var, and if not, fire the code adding a new items. Well, for some reason when I went to pick up the item the second time, the code that was supposed to add 1 to the quantity var didn't work, and instead the event mentioned above fired, BUT a new item wasn't created, even though the event fire and the new item code are in the same if block.

Code: Select all

local return_table = wesnoth.synchronize_choice(sync)
	if return_table.return_value == 1 or return_table.return_value == -1 then
		local u_id = wesnoth.get_variable("unit.id") 
		local check_var = string.format("%s.%s", u_id, "inventory")

		for i = 1, wesnoth.get_variable(check_var .. ".length") do
			local current_item_being_checked_id = wesnoth.get_variable(string.format("%s[%d].id", check_var, i - 1))
			if current_item_being_checked_id == cfg.id then
				local has_item = "true"
				local current_quantity = wesnoth.get_variable(string.format("%s[%d].quantity", check_var, i - 1))
				wesnoth.set_variable(string.format("%s[%d].quantity", check_var, i - 1), current_quantity + 1)
			end
		end

		if has_item ~= "true" then
			local i_index = wesnoth.get_variable(string.format("%s.%s.%s", u_id, cfg.section, "length"))
			local var_path = string.format("%s.%s[%i]", u_id, "inventory", i_index)

			local item_action = helper.get_child(cfg, "command")
			local remove_action = helper.get_child(cfg, "remove_command")

			wesnoth.set_variable(var_path .. ".id", cfg.id)
			wesnoth.set_variable(var_path .. ".name", cfg.name)
			wesnoth.set_variable(var_path .. ".quantity", 1)
			wesnoth.set_variable(var_path .. ".image", cfg.image)
			wesnoth.set_variable(var_path .. ".description", cfg.description)
			wesnoth.set_variable(var_path .. ".command", item_action.__literal)
			wesnoth.set_variable(var_path .. ".remcommand", remove_action.__literal)

			wesnoth.fire_event(cfg.id)
		end
	end
Any ideas? BTW, I still have the said [event] as a sub-event of the moveto:

Code: Select all

[event]
        name=moveto
        # wmllint: recognize main_key_pickup
        id=main_key_pickup
        first_time_only=no
        [filter]
            x,y=26,16
        [/filter]

        [inventory_item]
            # wmllint: recognize scen1_key
            id=scen1_key
            name= _ "Key"
            image=icons/key.png
            description= _ "An old, but well taken care of, key. It appears to be down here for safekeeping and can be used to open certain locked gates."
            section=items
            [command]
            [/command]
            [remove_command]
            [/remove_command]
        [/inventory_item]

        [event]
            name=scen1_key
            [message]
                speaker=unit
                message= _ "I've found it! The key is ours!"
            [/message]

            [message]
                speaker=Galamor
                message= _ "Good! Now we can escape this cesspool."
            [/message]

            [message]
                speaker=Norethial
                message= _ "Good! Now we can escape. Bring it here, I want to get out of here as fast as possible."
            [/message]

            {PLACE_IMAGE (items/chest-plain-open.png) 26 16}

            [event]
                id=main_key_pickup
                remove=yes
            [/event]
        [/event]

        {VARIABLE has_key yes}
    [/event]
I did move to pick up the item a third time to confirm it had been removed, and it had.
Creator of Shadows of Deception (for 1.12) and co-creator of the Era of Chaos (for 1.12/1.13).
SurvivalXtreme rocks!!!
What happens when you get scared half to death...twice?
User avatar
vultraz
Developer
Posts: 960
Joined: February 7th, 2011, 12:51 pm
Location: Dodging Daleks

Re: vultraz's lua questions

Post by vultraz »

I just realized yesterday that maybe a multipage isn't needed. I can just change the values if the listbox entries with set_dialog_value. :doh: Unfortunatelty, that leaves open the question of how to deal with items left over if the number of new items being inserted > the old number of items. There are some cool functions in C++ ( see src/gui/widgets/listbox.hpp) that could deal with these problems (and maybe allow some cool new features ^_^ ), but AFAIK, they're not usuable in lua. :augh: I could try to make them so, but then they wouldn't be available 'till 1.11.0 is realeased in a few months time. :hmm: PLUS I'm not sure how any of the lua functins are set up. AFAICT they're writen in C++ and somehow get passed to the lua engine, so would making a new lua function and making it call the relative C++ listbox stuff work? I'm really not sure. :P

Also, I was able to get my event to fire correctly by making it a main event instead of a sub event. :)
Creator of Shadows of Deception (for 1.12) and co-creator of the Era of Chaos (for 1.12/1.13).
SurvivalXtreme rocks!!!
What happens when you get scared half to death...twice?
AI
Developer
Posts: 2396
Joined: January 31st, 2008, 8:38 pm

Re: vultraz's lua questions

Post by AI »

Hmm, I think I may be able to extend the listbox-hack to write a GUI2 preferences dialog when I get the time.
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: vultraz's lua questions

Post by Anonymissimus »

vultraz wrote:I'm not sure how any of the lua functins are set up. AFAICT they're writen in C++ and somehow get passed to the lua engine, so would making a new lua function and making it call the relative C++ listbox stuff work? I'm really not sure. :P
Regarding the functions such as
static int intf_message(lua_State *L),
adding one using the same pattern and adding it to the
static luaL_Reg const callbacks[]
should work. You should understand how the functions communicate with the lua script that calls it, and have your test setup so that you can leave the debugger always open while testing changed stuff so that you don't need to relaunch it since we know it takes minutes.
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml startersPlan Your Advancements: mp mod
The Earth's Gut: sp campaignSettlers of Wesnoth: mp scenarioWesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
User avatar
vultraz
Developer
Posts: 960
Joined: February 7th, 2011, 12:51 pm
Location: Dodging Daleks

Re: vultraz's lua questions

Post by vultraz »

Ok, another question. :P
I'm trying to make my inventory set the values of labels and stuffs in rows that excede the number of items in the list being generated, since currently you can't remove rows... :augh:

Code: Select all

-- Prints item list. Kept in a function because it will need to be called later again.
		local u_id = wesnoth.get_variable("unit.id")
		local prev_max_list_index = 0
		local inv_list_data = {}
		local function print_item_list()
			inv_list_data = {}
			local var = string.format("%s.%s", u_id, "inventory")
			-- Deposit stuff in a table first for easy use later
			for i = 1, wesnoth.get_variable(var .. ".length") do
				table.insert(inv_list_data, { image = wesnoth.get_variable(string.format("%s[%d].image", var, i - 1)), 
						              name = wesnoth.get_variable(string.format("%s[%d].name", var, i - 1)),
						              description = wesnoth.get_variable(string.format("%s[%d].description", var, i - 1)),
						              quantity = wesnoth.get_variable(string.format("%s[%d].quantity", var, i - 1)) })
			end

			-- And print options from that
			for i = 1, #inv_list_data do
				wesnoth.set_dialog_value(inv_list_data[i].image, "inventory_list", i, "list_image")
				wesnoth.set_dialog_value(inv_list_data[i].name, "inventory_list", i, "list_name")
				wesnoth.set_dialog_value(inv_list_data[i].quantity, "inventory_list", i, "list_quantity")
			end

			max_list_index = #inv_list_data
			if max_list_index < prev_max_list_index then
				for i = max_list_index + 1, prev_max_list_index do
					wesnoth.set_dialog_value("", "inventory_list", i, "list_image")
					wesnoth.set_dialog_value("", "inventory_list", i, "list_name")
					wesnoth.set_dialog_value("", "inventory_list", i, "list_quantity")
					wesnoth.set_dialog_value("", "inventory_list", i, "list_active")
				end
			end
			-- Refresh var value
			prev_max_list_index = max_list_index
		end

		-- Sets the Give/Take button's value based on category selection
		local function select_category_effect()
			local category = wesnoth.get_dialog_value("category_list")
			-- Set button value
			if category == 1 then
				wesnoth.set_dialog_value("Give Items", "give_take_button")
			else
				wesnoth.set_dialog_value("Take Items", "give_take_button")
			end
			-- Refresh item list
			print_item_list()
		end
For some reason, this doesn't happen in my tests. Unit 1 has 1 item, but when you switch to a unit's category that has 1 item, the option isn't set to "". Dunno why. Since the print_item_list is called in the preshow function, therefor prev_max_list_index and max_list_index should be initialized, therefor making the if max_list_index < prev_max_list_index then run as true, and it should work. Eh...not sure if I'm making much sense, but the bottom line is it doesn't work. Any suggestions?
Creator of Shadows of Deception (for 1.12) and co-creator of the Era of Chaos (for 1.12/1.13).
SurvivalXtreme rocks!!!
What happens when you get scared half to death...twice?
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: vultraz's lua questions

Post by Elvish_Hunter »

vultraz wrote:For some reason, this doesn't happen in my tests. Unit 1 has 1 item, but when you switch to a unit's category that has 1 item, the option isn't set to "". Dunno why.
Since I haven't tested your code, I don't yet have an idea. However, masking exceeding options with set_dialog_value( "" ) may be dangerous. Explanation: when I did it yesterday in a chunk of code, the option did not appear. So, it wasn't selectable using the mouse. But, when I scrolled the listbox with the arrow keys, the blue bar disappeared. Why? Because the masked option was the one selected in that moment! At this point, one can click OK (or any other button that does something based on the selected option) and introduce a bug. Apparently, our listboxes are not designed to be dinamically modified...
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)
User avatar
vultraz
Developer
Posts: 960
Joined: February 7th, 2011, 12:51 pm
Location: Dodging Daleks

Re: vultraz's lua questions

Post by vultraz »

Hum....oh well then... :( I guess I'll try to code some new features for the lua GUI bindings (eg removing listbox rows, which is available in C++) and complete my inventory in 1.11. Though, BTW, I'm not sure the problem you state would affect me, as the blanked-out rows would still have their checkboxes, but that still would cause other problems...like needing an empty table for the selection callback....blagh. 1.11 it is!
Creator of Shadows of Deception (for 1.12) and co-creator of the Era of Chaos (for 1.12/1.13).
SurvivalXtreme rocks!!!
What happens when you get scared half to death...twice?
User avatar
vultraz
Developer
Posts: 960
Joined: February 7th, 2011, 12:51 pm
Location: Dodging Daleks

Re: vultraz's lua questions

Post by vultraz »

Annnndddd, another question!

Code: Select all

---
-- Checks every unit matching the SUF's inventory for an certain item and executes some code
-- if it is found
--
-- [check_inventory]
--     [filter][/filter]
--     item=id
--     [then][/then]
-- [/check_inventory]
---
function wml_actions.check_inventory(cfg)
	local filter = helper.get_child(cfg, "filter") or
		helper.wml_error "[check_inventory] missing required [filter] tag"
	filter.role = "hero"
	local units = wesnoth.get_units(filter)

	for i, u in ipairs(units) do
		local u_id = units[i].id
		local items_carried = helper.get_variable_array(string.format("%s.%s", u_id, "inventory"))

		for ii,k in ipairs(items_carried) do
			if items_carried[ii].id == cfg.item then
				local stuff_to_do = helper.get_child(cfg, "then") or
					helper.wml_error "[check_inventory] missing required [then] tag"
				wesnoth.fire(stuff_to_do.__literal)
				return
			end
		end
	end
end
What I want to do is get the contents of [filter], add a value for .role, and then get an array with the units that match that criteria, but it seems this line:

Code: Select all

filter.role = "hero"
doesn't work. Is there some other way I an inject a value for .role into what it gets out of [filter]?
Creator of Shadows of Deception (for 1.12) and co-creator of the Era of Chaos (for 1.12/1.13).
SurvivalXtreme rocks!!!
What happens when you get scared half to death...twice?
Post Reply