Ceres' Lua Problems

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

Moderator: Forum Moderators

Ceres
Forum Regular
Posts: 620
Joined: September 18th, 2010, 7:56 pm
Location: Germany

Re: Ceres' Lua Problems

Post by Ceres »

Now the stderr.txt complains that altar_goto[0].x is an invalid WML array index :augh:
Is it impossible to set indexes like that?
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: Ceres' Lua Problems

Post by Anonymissimus »

Ceres wrote:Now the stderr.txt complains that altar_goto[0].x is an invalid WML array index :augh:
Should happen if the wml array value altar_goto[0].x doesn't exist when evaluating the variable (but not when setting it).

EDIT
Here's the lua part improved with the error above supposed to disappear (untested):

Code: Select all

		local helper = wesnoth.require "lua/helper.lua"
		local altar_victims = helper.get_variable_array "altar_victims"
		wesnoth.set_variable("altar_goto")
		for i, v in ipairs(altar_victims) do
			local altar_path = wesnoth.find_path (v.x, v.y, 22, 14, {ignore_units = false, viewing_side = 0})
			wesnoth.set_variable ("altar_goto[" .. i-1 .. "].x", altar_path[i][1])
			wesnoth.set_variable ("altar_goto[" .. i-1 .. "].y", altar_path[i][2])
			wesnoth.set_variable ("altar_goto[" .. i-1 .. "].id", v.id)
		end
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
Ceres
Forum Regular
Posts: 620
Joined: September 18th, 2010, 7:56 pm
Location: Germany

Re: Ceres' Lua Problems

Post by Ceres »

:shock: :D
It actually worked (the evaluated coordinates were the hex the unit was standing on, but I figured it out myself)! Thank you all so much!
Lua doesn't seem to like me, so I'd better stay wth WML for now.
Edit+repost: Sigh. Sometimes it's working as I want it, but often the code spawns this:
20110718 17:32:10 error scripting/lua: [string "..."]:7: attempt to index field '?' (a nil value)
stack traceback:
[string "..."]:7: in function 'bytecode'
...(x86)/Battle for Wesnoth 1.9.7/data/lua/wml-tags.lua:247: in function 'cmd'
...(x86)/Battle for Wesnoth 1.9.7/data/lua/wml-tags.lua:290: in
function 'handle_event_commands'
...(x86)/Battle for Wesnoth 1.9.7/data/lua/wml-tags.lua:305: in
function 'if_while_handler'
...(x86)/Battle for Wesnoth 1.9.7/data/lua/wml-tags.lua:311: in function 'cmd'
...(x86)/Battle for Wesnoth 1.9.7/data/lua/wml-tags.lua:290: in
function 'handle_event_commands'
...(x86)/Battle for Wesnoth 1.9.7/data/lua/wml-tags.lua:305: in
function 'if_while_handler'
...(x86)/Battle for Wesnoth 1.9.7/data/lua/wml-tags.lua:315: in function 'cmd'
...(x86)/Battle for Wesnoth 1.9.7/data/lua/wml-tags.lua:290: in
function <...(x86)/Battle for Wesnoth 1.9.7/data/lua/wml-tags.lua:254>
20110718 17:32:10 error engine: Formula in WML string cannot be
evaluated due to Could not parse expression --> "9 13 "

Code:
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: Ceres' Lua Problems

Post by Elvish_Hunter »

Ceres wrote:error scripting/lua: [string "..."]:7: attempt to index field '?' (a nil value)
And at line 7 we have...

Code: Select all

wesnoth.set_variable ("altar_goto[" .. i-1 .. "].x", altar_path[i+1][1])
Here, the only thing that can be nil is altar_path[i+1][1]. I'm not sure, as it's always hard to guess what goes wrong, but what about trying to replace it with altar_path[i][1] ?
Also, a suggestion: when there are such problems, use print() to check the values of suspicious variables. It can be really helpful. :)
Last edited by Elvish_Hunter on August 22nd, 2011, 10:19 am, edited 1 time in total.
Reason: Fixed a too large font size that I used.
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)
Ceres
Forum Regular
Posts: 620
Joined: September 18th, 2010, 7:56 pm
Location: Germany

Re: Ceres' Lua Problems

Post by Ceres »

:hmm:
That's what it was before, but it seemed to evaluate the wrong hex, namely the one the unit is standing on. My code was working sometimes, but not always.
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: Ceres' Lua Problems

Post by Elvish_Hunter »

So, I tested your code, by putting it in a [set_menu_item] to make my life simpler. There were some things to notice:
- first, why use get_variable_array when you can simply use wesnoth.get_units?
- to move the units of one hex, you needed to use the second step in the iterator returned by find_path. Using index+1 had the consequence of attempting to read on-existent steps.
- to pass the radius parameter, I used the (...) table, that collects everything that is supplied in the [args] tag.
- I also used string.format instead of multiple concatenations.
See here:
Spoiler:
I left (but commented) all the print() lines, so you can see how I tracked down the bug. I also change the variable names to be long and more understandable. If there is anything unclear, just ask. :)
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)
Ceres
Forum Regular
Posts: 620
Joined: September 18th, 2010, 7:56 pm
Location: Germany

Re: Ceres' Lua Problems

Post by Ceres »

At first I thought that something in your code was broken, but then I noticed you changed the hex the units are pulled towards from 22;14 to 20;14, whyever.
Apart from that, you kindly healed my ailing code (forever now, hopefully) :)
One thing I want to know since months: what exactly is ipairs() doing? I looked for tutorials and references, but always lost the thread somewhere...
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: Ceres' Lua Problems

Post by Elvish_Hunter »

I needed to change the location only because of the map that I used, that was 20 x 20.
About ipairs, it iterates through a table, and for every item it returns a numeric value (index) and the item itself. More informations are available at lua-users.org .
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)
Ceres
Forum Regular
Posts: 620
Joined: September 18th, 2010, 7:56 pm
Location: Germany

Re: Ceres' Lua Problems

Post by Ceres »

Yet another question: What's the difference between tables, WML tables and proxy units?
Luther
Posts: 128
Joined: July 28th, 2007, 5:19 pm
Location: USA

Re: Ceres' Lua Problems

Post by Luther »

A WML table is a table that can be translated directly to WML. They're very complicated to type without using set_wml_tag_metatable. The following Lua and WML are equivalent:

Lua:

Code: Select all

H = wesnoth.require('lua/helper.lua')
T = H.set_wml_tag_metatable{}

{
  --x, y, and radius are WML attributes
  x = 84,
  y = 42,
  radius = 1,

  --This is a [filter_radius] tag with its own WML table
  T.filter_radius{
    terrain = 'K*,C*'
  }
}
WML:

Code: Select all

x=84
y=42
radius=1
[filter_radius]
  terrain=K*,C*
[/filter_radius]
A proxy unit is like a table, but it gives you direct access to a unit in the engine. A full description is at LuaWML:Units. You cannot write one from scratch. It must be returned by one of the functions on that wiki page.

Let us know if you need any clarification.
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: Ceres' Lua Problems

Post by Anonymissimus »

A wml table is a normal lua table which additionally fullfills several syntax rules. I listed them somewhere in my lua thread (at the time I wrote the dbms function from the WLP).
A proxy unit is like a table
When dumped by calling the __cfg field, yes. Other than that it's a read-only lua userdata which is owned by the C++ code which allows you several ways of accessing and modifying.
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: Ceres' Lua Problems

Post by Elvish_Hunter »

Just for completeness, the code posted by Luther will be the following, if you don't use set_wml_tag_metatable:

Code: Select all

{
  x = 84,
  y = 42,
  radius = 1,
  { "filter_radius", { terrain = 'K*,C*' } }
}
If you do not want to use the metatable, the rule is to create a table where the first element is the tag name ( "filter_radius" ), and the second element is another table containing all the keys and values ( { terrain = 'K*,C*' } ).
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)
Ceres
Forum Regular
Posts: 620
Joined: September 18th, 2010, 7:56 pm
Location: Germany

Re: Ceres' Lua Problems

Post by Ceres »

Thank you. All right then, I messed around with this code for hours now trying to create a [find_path] tag. Yet Wesnoth complains about
"attempt to index field '?' (a number value)".
Could someone kindly point out where this error comes from? I tried to franken-code as much as possible from working snippets, but apparently I failed somewhere.

Code: Select all

function wml_actions.find_path(cfg)
	local variable = cfg.variable or "path"
	local unit = wesnoth.get_units(helper.get_child(cfg, "filter"))[1]
	local to_x = cfg.to_x
	local to_y = cfg.to_y
	local findpath = wesnoth.find_path ( unit.x, unit.y, to_x, to_y, { ignore_units = false})
	for i, v in ipairs(findpath) do
		wesnoth.set_variable(string.format(variable .. "[%d].x", i-1), v[i][1])
		wesnoth.set_variable(string.format(variable .. "[%d].y", i-1), v[i][2])
	end
end
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: Ceres' Lua Problems

Post by Anonymissimus »

untested:

Code: Select all

function wml_actions.find_path(cfg)
	local variable = cfg.variable or "path"
	local unit = wesnoth.get_units(helper.get_child(cfg, "filter"))[1]
	local to_x = cfg.to_x
	local to_y = cfg.to_y
	local findpath = wesnoth.find_path ( unit.x, unit.y, to_x, to_y, { ignore_units = false})
	for i, v in ipairs(findpath) do
		wesnoth.set_variable(string.format(variable .. "[%u].x", i-1), v[1])
		wesnoth.set_variable(string.format(variable .. "[%u].y", i-1), v[2])
	end
end
The structure of the arrays returned by find_path and get_locations is like { {a, b}, {c, d}, ... } so v in this loop will be {a, b} and then {b, c}, ...
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: Ceres' Lua Problems

Post by Elvish_Hunter »

Ceres wrote:I messed around with this code for hours now trying to create a [find_path] tag.
In case that you are interested, some months ago I created a [find_path] tag, that is available in the Wesnoth Lua Pack. :)
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)
Post Reply