Change a lua code to support lists

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

Moderator: Forum Moderators

Post Reply
User avatar
Toranks
Translator
Posts: 168
Joined: October 21st, 2022, 8:59 pm
Location: Sevilla
Contact:

Change a lua code to support lists

Post by Toranks »

I've been using this code for a long time (not mine) to remove objects in all units, including units in the recall list, an advantage that the usual [remove_object] tag doesn't have.

Code: Select all

function wesnoth.wml_actions.aww_remove_object(cfg)
    local object_id = cfg.object_id
    for _,unit in ipairs(wesnoth.units.find(cfg)) do
        wesnoth.units.remove_modifications(unit, {id = object_id})
    end
end

Code: Select all

[aww_remove_object]
    object_id=object_id
[/aww_remove_object]
How could I make it support a comma separated list as well? I have many objects to delete in some events, and It would save me a lot of lines.

Code: Select all

[aww_remove_object]
    object_id=object_a,object_b,object_c,etc
[/aww_remove_object]
By the way, it would be nice if something like this was included in the Wesnoth Lua Pack addon.
Last edited by Toranks on February 11th, 2023, 3:53 am, edited 1 time in total.
User avatar
Celtic_Minstrel
Developer
Posts: 2214
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Change a lua code to support lists

Post by Celtic_Minstrel »

We already have that.

By default it implements the more advanced splitting algorithm used elsewhere in Wesnoth, where commas enclosed in parentheses are not counted for the split.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
Toranks
Translator
Posts: 168
Joined: October 21st, 2022, 8:59 pm
Location: Sevilla
Contact:

Re: Change a lua code to support lists

Post by Toranks »

Code: Select all

function wesnoth.wml_actions.aww_remove_object(cfg)
	local object_id_list = stringx.split(cfg.object_id)
	for _,unit in ipairs(wesnoth.units.find(cfg))
	do
		for _,i in ipairs(object_id_list)
		do
			wesnoth.units.remove_modifications(unit, {id = object_id_list[i]})
		end
	end
end
After several tries, I managed to get the errors to stop appearing and any things to be deleted xD. But... that it deletes all the objects on all units!
Where have I done wrong?
User avatar
Celtic_Minstrel
Developer
Posts: 2214
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Change a lua code to support lists

Post by Celtic_Minstrel »

Your inner loop is wrong.

for _,i in ipairs(object_id_list)

This assigns the index of the object to the variable _ and the specific object ID to the variable i. So for example, _ is 1 and i is "object_a".

{id = object_id_list[i]}

Now, i is (for example) "object_a", but object_id_list is an "array", which means it has only integer keys (eg, object_id_list[1] is "object_a"). So, object_id_list.object_a is nil. Setting id = nil is the same as not setting it at all, so this is equivalent to:

wesnoth.units.remove_modifications(unit, {})

An empty filter matches everything. So, all objects are removed.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
Toranks
Translator
Posts: 168
Joined: October 21st, 2022, 8:59 pm
Location: Sevilla
Contact:

Re: Change a lua code to support lists

Post by Toranks »

Code: Select all

function wesnoth.wml_actions.aww_remove_object(cfg)
	local object_id_list = stringx.split(cfg.object_id)
	for _,unit in ipairs(wesnoth.units.find(cfg))
	do
		for i in ipairs(object_id_list)
		do
			wesnoth.units.remove_modifications(unit, {id = object_id_list[i]})
		end
	end
end
I just tried it and it works, thanks!
It's right? At the moment it does not seem to have false positives or negatives
gnombat
Posts: 706
Joined: June 10th, 2010, 8:49 pm

Re: Change a lua code to support lists

Post by gnombat »

Toranks wrote: February 11th, 2023, 5:33 am I just tried it and it works, thanks!
It's right? At the moment it does not seem to have false positives or negatives
You could also write it like this (it should work exactly the same, but it might be a tiny bit faster):

Code: Select all

function wesnoth.wml_actions.aww_remove_object(cfg)
	local object_id_list = stringx.split(cfg.object_id)
	for _,unit in ipairs(wesnoth.units.find(cfg))
	do
		for i,object_id in ipairs(object_id_list)
		do
			wesnoth.units.remove_modifications(unit, {id = object_id})
		end
	end
end
If you do that, you no longer need the i variable, so you could change it to _ (which is the usual convention for an unused variable):

Code: Select all

function wesnoth.wml_actions.aww_remove_object(cfg)
	local object_id_list = stringx.split(cfg.object_id)
	for _,unit in ipairs(wesnoth.units.find(cfg))
	do
		for _,object_id in ipairs(object_id_list)
		do
			wesnoth.units.remove_modifications(unit, {id = object_id})
		end
	end
end
Post Reply