Crendgrim's Lua Thread

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

Moderator: Forum Moderators

User avatar
Crendgrim
Moderator Emeritus
Posts: 1328
Joined: October 15th, 2010, 10:39 am
Location: Germany

Crendgrim's Lua Thread

Post by Crendgrim »

So I started to learn Lua, too. I'll use this thread to ask questions which will come up during my learning phase.

The first is already there:

I'm creating an (easy) inventory system, because I think that this will be useful for some future add-ons of mine while being not too difficult.
After some initial problems with translated strings (thanks to Anonymissimus for explaining me that issue) I successfully created two little WML tags called [cg_init_inventory] and [cg_inventory_size]. Actually, I'm going to remove the first, because the latter does everything now: Initialize an inventory by setting its size as well as modifying this size.
However, I'm stuck at [cg_item_add]. This tag is supposed to add an item to the unit's inventory. For now, it only takes a SUF to get all wanted units and a "name" attribute for the item's name.
Yesterday evening I some problem, so I decided to take a look again today. However, this didn't fix it.

So, getting to my actual problem, I'll post my code. The comments should explain what it's supposed to do.

Code: Select all

--[[ [cg_item_add]
This tag adds an item.
Arguments:
 - StandardUnitFilter
 - name: the item's name
]]
function wml_actions.cg_item_add(cfg)
  
  local filter = wesnoth.get_units(helper.get_child(cfg, "filter")) or helper.wml_error("[cg_item_add] missing required [filter] tag")
  local name = cfg.name or helper.wml_error("Missing required name= attribute in [cg_item_add]")
  
  local newitem = { name = name }
  
  for index, unit in ipairs(filter) do
    
    -- if cg_inventory_size isn't set or equals zero, the unit has no inventory, so we skip the following process
    if unit.variables.cg_inventory_size and unit.variables.cg_inventory_size ~= 0 then
    
      local items = {} -- creating an empty array
      if unit.variables.cg_items then items = helper.get_variable_array("unit.variables.cg_items") end -- if possible, retrieve information from the unit's variables

      if #items >= unit.variables.cg_inventory_size then -- do we still have some place for the item?
        
        wesnoth.message(tostring(unit.name), "No place in inventory!")
        
      else
      
        table.insert(items, newitem) -- insert the new item

        helper.set_variable_array("unit.variables.cg_items", items) -- saving it. See below.
      
      end -- if (size)
      
    end -- if (inventory)

  end -- for
  
end -- function
The problem is that this doesn't save the data to the unit's variables, but to a WML variable "unit".
How is this done correctly?


Crend
UMC Story Images — Story images for your campaign!
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: Crendgrim's Lua Thread

Post by Anonymissimus »

You can try adding wesnoth.put_unit(wesnoth.get_variable("unit")) after the
helper.set_variable_array("unit.variables.cg_items", items)
line if your code works otherwise.
But note that it depends on the existance of a wml variable "unit", so won't work in many types of events, and is somewhat inefficient then. YOu can add wesnoth.set_variable("unit", unit.__cfg) above the
if unit.variables.cg_items then items = helper.get_variable_array("unit.variables.cg_items") end
line to remove the dependency on the variable existance.

The way to go is calling unit=unit.__cfg near the start of your loop for every unit to modify I'm pretty sure, but since I'm not silene I can't post some modified code of yours now which is likely enough to work untested. :hmm: :augh: :doh:

trying anyway (completely untested) :hmm:

Code: Select all

--[[ [cg_item_add]
This tag adds an item.
Arguments:
- StandardUnitFilter
- name: the item's name
]]
function wml_actions.cg_item_add(cfg)

	local units = wesnoth.get_units(helper.get_child(cfg, "filter")) or helper.wml_error("[cg_item_add] missing required [filter] tag")
	local name = cfg.name or helper.wml_error("Missing required name= attribute in [cg_item_add]")

	local newitem = { name = name }

	for index, unit in ipairs(units) do

		-- if cg_inventory_size isn't set or equals zero, the unit has no inventory, so we skip the following process
		local i_size = unit.variables.cg_inventory_size
		if i_size and i_size ~= 0 then
			unit = unit.__cfg --since for proxy unit.variables "only toplevel named fields are proxied", convert to a wml table
			local variables = helper.get_child(unit, "variables")

			if #variables >= i_size then -- do we still have some place for the item?
				--comparison works only if you have no other unnamed fields in the variable table (no other arrays under the [variables] tag)
				wesnoth.message(tostring(unit.name), "No place in inventory!")
			else
				table.insert(variables, {"cg_items", newitem }) -- insert the new item
				wesnoth.put_unit(unit)
			end -- if (size)
		end -- if (inventory)
	end -- for
end -- function
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
Crendgrim
Moderator Emeritus
Posts: 1328
Joined: October 15th, 2010, 10:39 am
Location: Germany

Re: Crendgrim's Lua Thread

Post by Crendgrim »

Thanks a lot :)
Your code worked without any modifications, so it looks as if you were becoming a second silene :P

However, I changed it a bit to create a slightly different structure (unit.variables.cg_items.item for each item), so counting items in the inventory is easier now.
This way it works completely as it's supposed to be:

Code: Select all

--[[ [cg_item_add]
This tag adds an item.
Arguments:
 - StandardUnitFilter
 - name: the item's name
]]
function wml_actions.cg_item_add(cfg)
  
  local filter = wesnoth.get_units(helper.get_child(cfg, "filter")) or helper.wml_error("[cg_item_add] missing required [filter] tag")
  local name = cfg.name or helper.wml_error("Missing required name= attribute in [cg_item_add]")
  
  local newitem = { name = name }
  
  for index, unit in ipairs(filter) do
    
    -- if cg_inventory_size isn't set or equals zero, the unit has no inventory, so we skip the following process
    local i_size = unit.variables.cg_inventory_size
    if i_size and i_size ~= 0 then
        
      unit = unit.__cfg --since for proxy unit.variables "only toplevel named fields are proxied", convert to a wml table
      local variables = helper.get_child(unit, "variables")
      local insert = false
      local items = helper.get_child(variables, "cg_items")
      if not items then -- isn't there an inventory yet? Let us create one...
        items = {}
        insert = true
      end

      if #items >= i_size then -- do we still have some place for the item?
        wesnoth.message(tostring(unit.name), "No place in inventory!")
      else
        table.insert(items, {"item", newitem}) -- insert the new item
        if insert then table.insert(variables, {"cg_items", items}) end -- insert [cg_items] tag if needed
        wesnoth.put_unit(unit) -- store information
         
      end
      
    end

  end
  
end
Now I'm only curious about that unit = unit.__cfg part, because it looks as if that was the key solution. What exactly does that do?


Crend
UMC Story Images — Story images for your campaign!
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: Crendgrim's Lua Thread

Post by Anonymissimus »

Crendgrim wrote:Now I'm only curious about that unit = unit.__cfg part, because it looks as if that was the key solution. What exactly does that do?
It transforms a lua proxy unit variable, which is an accessor to an instance of the C++ class "unit" from unit.hpp into a wml table describing a unit. (in this case - other types of proxy variables can have a __cfg field too) The process is similar like storing an on-map unit into a wml variable with [store_unit]. In fact, it's the same, since [store_unit] does just call the __cfg field as you can see in its implementation in data/lua/wml-tags.lua.
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
Crendgrim
Moderator Emeritus
Posts: 1328
Joined: October 15th, 2010, 10:39 am
Location: Germany

Re: Crendgrim's Lua Thread

Post by Crendgrim »

Okay, thanks. I think I got that. ;)

[cg_item_add] and [cg_item_remove] are working now also for multiple units. :)

However, the next problem is appearing. This time I'm not sure whether it's better doable in WML or in Lua, but I ask it here nevertheless for I already started here.

So, I created another tag [cg_show_inventory] which outputs a message with all items available. Later I plan to implement there some functionality to use certain items as weapons etc.
My plan is to make this function accessible via a menu_item in the menu. I'm currently doing it this way:

Code: Select all

[event]

  name=prestart
  [set_menu_item]
    id=cg_show_inventory_item
    description= _ "Show Inventory"
    [show_if]
      [have_unit]
        side=$side_number
        x=$x1
        y=$y1
        [not]
          [filter_wml]
            [variables]
              cg_inventory_size=0
            [/variables]
          [/filter_wml]
        [/not]
      [/have_unit]
    [/show_if]
    [command]
      [cg_show_inventory]
        x=$x1
        y=$y1
      [/cg_show_inventory]
    [/command]
  [/set_menu_item]

[/event]
The problem is that this way also units without an inventory (without the variable "cg_inventory_size") get the menu item.
Is there any way to test via WML if a certain variable exists? Or, alternatively, how would this menu be implemented in Lua?


Crend
UMC Story Images — Story images for your campaign!
User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

Re: Crendgrim's Lua Thread

Post by 8680 »

Try greater than 0 instead of not 0.
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: Crendgrim's Lua Thread

Post by Anonymissimus »

(untested)
load a global function

Code: Select all

function cg_has_inventory(unit)
    return unit.variables.cg_inventory_size
end
and then use [have_unit]lua_function="cg_has_inventory"
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
Crendgrim
Moderator Emeritus
Posts: 1328
Joined: October 15th, 2010, 10:39 am
Location: Germany

Re: Crendgrim's Lua Thread

Post by Crendgrim »

8680:
How can that be done in a [variables] tag?

Anonymissimus:
Great!
I didn't know that this worked.. I should read the Wiki more carefully. :oops:
Thanks a lot, this should fix it :)


Crend
UMC Story Images — Story images for your campaign!
User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

Re: Crendgrim's Lua Thread

Post by 8680 »

Crendgrim wrote:8680: How can that be done in a [variables] tag?
I... oh. :doh: I guess I only skimmed your code; and I also guess it's been too long since I used WML. Apologies. Apologies. I'll go away now.
User avatar
Crendgrim
Moderator Emeritus
Posts: 1328
Joined: October 15th, 2010, 10:39 am
Location: Germany

Re: Crendgrim's Lua Thread

Post by Crendgrim »

I just thought I had missed something ;)


Okay, I finally managed to create a working inventory system. It's very WIP (since the items can't do anything right now), but it works .. somehow.
I'm pretty sure that it can be done nicer in many parts, but hey! at least it works :)

Features:
  • inventories for multiple units
  • change inventory size
  • place and remove items
  • drop items from the inventory
  • on stepping on an item the unit can take it up
  • items can have names, images and descriptions
So, here is my lua file:
inventory.lua

Code: Select all

local helper = wesnoth.require "lua/helper.lua"
local items = wesnoth.require "lua/wml/items.lua"
local location_set = wesnoth.require "lua/location_set.lua"

wml_actions = wesnoth.wml_actions

-- #textdomain "cg-inventory"
_ = wesnoth.textdomain "cg-inventory"

--[[ [cg_init_inventory]
Initializes a unit's inventory.
Arguments:
 - StandardUnitFilter
 - size (optional): setting the size to a specified value. If not given, size 1 is used.
]]
function wml_actions.cg_init_inventory(cfg)
  
  local filter = wesnoth.get_units(cfg)
  local size = cfg.size or 1 -- default
  
  for index, unit in ipairs(filter) do
    
    unit.variables.cg_inventory_size = size
    
  end
  
end

--[[ [cg_inventory_size]
This tag changes a unit's inventory size.
Arguments:
 - StandardUnitFilter
 - size (optional): setting the size to a fixed value
 - add (optional): adding a value to the inventory's size. You can also use negative values here.
If neither size nor add is given, the unit's inventory size will be set to 1.
You can set the unit's inventory size to 0 or nil to disable it.
]]
function wml_actions.cg_inventory_size(cfg)
  
  local filter = wesnoth.get_units(cfg)
  local size = cfg.size or 1
  local add = cfg.add or 0
  
  for index, unit in ipairs(filter) do
    
    if unit.variables.cg_inventory_size then
    
      if add ~= 0 then -- adding instead of changing to a fixed value
      
        local newsize = unit.variables.cg_inventory_size + add
      
        if newsize < 0 then -- don't go under zero
          newsize = 0
        end
      
        unit.variables.cg_inventory_size = newsize
      
      else
      
        unit.variables.cg_inventory_size = size
        
      end
      
    end
    
  end
  
end

--[[ [cg_item_add]
This tag adds an item.
Arguments:
 - [filter]: a StandardUnitFilter
 - id: the item's id
 - name: the item's name (translatable)
 - image (optional): an image for the item
 - description (optional): the item's description
]]
function wml_actions.cg_item_add(cfg)
  
  local filter = wesnoth.get_units(helper.get_child(cfg, "filter")) or helper.wml_error("[cg_item_add] missing required [filter] tag")
  local id = cfg.id or helper.wml_error("Missing required id= attribute in [cg_item_add]")
  local name = cfg.name or helper.wml_error("Missing required name= attribute in [cg_item_add]")
  local image = cfg.image
  local description = cfg.description
  
  local newitem = { id = id, name = name, image = image, description = description }
  
  for index, unit in ipairs(filter) do
    
    -- if cg_inventory_size isn't set or equals zero, the unit has no inventory, so we skip the following process
    local i_size = unit.variables.cg_inventory_size
    if i_size and i_size ~= 0 then
        
      unit = unit.__cfg --since for proxy unit.variables "only toplevel named fields are proxied", convert to a wml table
      local variables = helper.get_child(unit, "variables")
      local insert = false
      local items = helper.get_child(variables, "cg_items")
      if not items then -- isn't there an inventory yet? Let us create one...
        items = {}
        insert = true
      end

      if #items >= i_size then -- do we still have some place for the item?
        wesnoth.message(tostring(unit.name), tostring(_ "No place in inventory!"))
      else
        table.insert(items, {"item", newitem}) -- insert the new item
        if insert then table.insert(variables, {"cg_items", items}) end -- insert [cg_items] tag if needed
        wesnoth.put_unit(unit) -- store information
         
      end
      
    end

  end
  
end

--[[ [cg_item_add]
This tag removes an item.
Arguments:
 - [filter]: a StandardUnitFilter
 - id: the item's id
]]
function wml_actions.cg_item_remove(cfg)
  
  local filter = wesnoth.get_units(helper.get_child(cfg, "filter")) or helper.wml_error("[cg_item_remove] missing required [filter] tag")
  local id = cfg.id or helper.wml_error("Missing required id= attribute in [cg_item_remove]")
  
  for index, unit in ipairs(filter) do
    
    unit = unit.__cfg
    local variables = helper.get_child(unit, "variables")
    local items = helper.get_child(variables, "cg_items")
    
    if items and #items > 0 then -- only continue if unit has inventory
      
      local n = 0
      local found = false
      for item in helper.child_range(items, "item") do
      
        n = n + 1
        if item.id == id then
          found = true
          break
        end
      
      end
    
      if found then
      
        table.remove(items, n) -- remove item
        wesnoth.put_unit(unit) -- store information
      
      end
      
    end
    
  end
  
end

--[[ [cg_show_inventory]
This tag shows a unit's inventory
Arguments:
 - a StandardUnitFilter
]]
function wml_actions.cg_show_inventory(cfg)
  
  local filter = wesnoth.get_units(cfg)
  
  for index, unit in ipairs(filter) do
    
    local text = { speaker = unit.id, message = _ "My inventory includes:" }
    
    unit = unit.__cfg
    local variables = helper.get_child(unit, "variables")
    local items = helper.get_child(variables, "cg_items")
    
    table.insert(text, { "option", { message = _ "Exit", { "command", { { "set_variable", { name = "finished", value = "yes" } } } } } } )
    
    if items and #items > 0 then -- only continue if unit has inventory
      
      for item in helper.child_range(items, "item") do
        table.insert(text, { "option", { message = _ "&" .. item.image .. "=" .. item.name,
          { "command", { 
            { "message", {
              speaker = unit.id,
              message = "Item: " .. item.name .. "\n<span size='small'>" .. item.description .. "</span>",
              { "option", { message = _ "Back", { "command", {} } } },
              { "option", { message = _ "Drop Item", { "command", {
                { "cg_place_item", {
                  { "filter_location", { x = unit.x, y = unit.y } },
                  image = item.image,
                  id = item.id,
                  name = item.name,
                  description = item.description
                } },
                { "cg_item_remove", {
                  { "filter", { x = unit.x, y = unit.y } },
                  id = item.id
                } },
                -- Workaround: leave inventory and re-enter immediately
                { "set_variable", { name = "finished", value = "yes" } },
                { "cg_show_inventory", { x = unit.x, y = unit.y } }
              } } } }
            } }
          } }
        } })
      
      end
      
      wesnoth.set_variable("finished", "no")
      wesnoth.fire("while", {
        { "variable", { name = "finished", equals = "no" } },
        { "do", { { "message", text } } }
      })
    
    elseif variables.cg_inventory_size and variables.cg_inventory_size ~= 0 then -- just empty
      
      wesnoth.fire("message", { speaker = unit.id, message = _ "My inventory is empty." } )
      
    end
    
  end
  
end

--[[ cg_has_inventory
Checks if a unit has an inventory
To be used in [have_unit]
]]
function cg_has_inventory(unit)
  
  if unit.variables.cg_inventory_size and unit.variables.cg_inventory_size ~= 0 then return true else return false end
  
end


--[[ cg_place_item
Places an item at a certain location
Arguments:
 - [filter_location]: A StandardLocationFilter to get all locations to put this item on
 - image: the item's image
 - id: the item's id
 - name: the item's description (must be translatable)
 - description (optional): A description for the item
]]
function wml_actions.cg_place_item(cfg)
  
  local locations = wesnoth.get_locations( helper.get_child( cfg, "filter_location" ) ) or helper.wml_error( "Missing required [filter_location] in [cg_place_item]" )
  local image = cfg.image or helper.wml_error("Missing required image= attribute in [cg_place_item]")
  local id = cfg.id or helper.wml_error("Missing required id= attribute in [cg_place_item]")
  local name = cfg.name or helper.wml_error("Missing required name= attribute in [cg_place_item]")
  local description = cfg.description or ""
  
  local itemset = location_set.of_wml_var("cg_item_set")
  wesnoth.set_variable("cg_item_set", nil)

  for index, location in ipairs(locations) do
    
      itemset:insert(location[1], location[2])
    
      items.place_image(location[1], location[2], image)
    
      item = { {"filter", {x = location[1], y = location[2]}}, id = id, name = name, image = image, description = description }
  
      wesnoth.fire("event", {name = "moveto", first_time_only = "no", {"filter", {
          x = location[1], y = location[2], { "filter_location", { find_in = "cg_item_set" } }, lua_function = "cg_has_inventory"
        } }, { "message", {
          speaker = "unit",
          message = name .. "\n<span size='small'>" .. description .. "</span>\n\n" .. _ "Should I take this item?",
          { "option", {
            message = _ "Yes",
            { "command", {
              { "cg_item_add", item },
              { "cg_remove_item", {
                x = location[1],
                y = location[2]
              } }
            } }
          } },
          { "option", {
            message = _ "No",
            { "command", {} }
          } }
        } }
      })
      
    
  
  end
  
  itemset:to_wml_var("cg_item_set")
    
end

--[[ cg_remove_item
Removes all items at a certain location
Arguments:
 - a StandardLocationFilter to get all locations to remove items
]]
function wml_actions.cg_remove_item(cfg)
  
  local locations = wesnoth.get_locations(cfg)
  local itemset = location_set.of_wml_var("cg_item_set")
  wesnoth.set_variable("cg_item_set", nil)
  
  for index, location in ipairs(locations) do
    
    items.remove(location[1], location[2])
    itemset:remove(location[1], location[2])
    
  end
  
  itemset:to_wml_var("cg_item_set")
  
end
Actually, the very first function ([cg_init_inventory]) is redundant, because its job is also done by [cg_inventory_size]. I didn't change it yet only because I don't know whether [cg_init_inventory] will do more once (for example, setting up pre-defined items, other variables or whatever).

To use it, you have to do the following:
  • include the lua file in a preload event
  • put this code in your scenario:

    Code: Select all

    [event]
    
      name=prestart
      [set_menu_item]
        id=cg_show_inventory_item
        description= _ "Show Inventory"
        [show_if]
          [have_unit]
            side=$side_number
            x=$x1
            y=$y1
            lua_function=cg_has_inventory
          [/have_unit]
        [/show_if]
        [command]
          [cg_show_inventory]
            x=$x1
            y=$y1
          [/cg_show_inventory]
        [/command]
      [/set_menu_item]
    
    [/event]
  • Use [cg_init_inventory] with a StandardUnitFilter and a size= argument for each of your units who should get an inventory
  • Place items using [cg_place_item].
Maybe I'll upload an archive with a working configuration later.
For now I'm just glad that it finally works :mrgreen:

Future plans:
  • add item properties; e.g. heal, bonus, strength
  • allow certain items (with strength) to be equipped as weapons
  • make certain items undroppable
  • whatever comes to my mind :P

Crend

EDIT:
Archive attached as promised
Attachments
CGInventory.tar.gz
First version.
(4.01 KiB) Downloaded 521 times
UMC Story Images — Story images for your campaign!
User avatar
Crendgrim
Moderator Emeritus
Posts: 1328
Joined: October 15th, 2010, 10:39 am
Location: Germany

Re: Crendgrim's Lua Thread

Post by Crendgrim »

Okay, the last project I eventually abandoned, because nothing worked any more as expected. :P

But today I started another one, and I am again completely stuck. This time, I just want to have one inventory for the human player (inside a campaign), so I do not have to care about units and their respective items.

Code: Select all

function wml_actions.cg_inv_add(cfg)
  local id = cfg.id or helper.wml_error("Missing required id= attribute in [cg_inv_add]")
  local name = cfg.name or helper.wml_error("Missing required name= attribute in [cg_inv_add]")
  local image = cfg.image or helper.wml_error("Missing required image= attribute in [cg_inv_add]")
  local description = cfg.description or helper.wml_error("Missing required description= attribute in [cg_inv_add]")

  local item = wesnoth.create_unit { type = "CG Item", id = id, name = name, image = image, description = description }
  -- yes, it's a unit type I want to store

  local debug_utils = wesnoth.require("~add-ons/Wesnoth_Lua_Pack/debug_utils.lua")
  
  local inventory = helper.get_variable_proxy_array "cg_inventory"
  wesnoth.set_variable "qow_inventory"
  table.insert(inventory, {"item", item.__cfg} )
  debug_utils.dbms(inventory)
  -- and here is the weird thing:
  -- in the first tag call, dbms will verify that it's a WML table, but in the second call not.
  -- however, in both cases there is an error with the following command
  wesnoth.set_variable("cg_inventory", inventory)
  
end
I know I'm doing something terribly wrong, but I have no idea what actually. Besides, I changed the above code so often that it's quite possible that it once was more correct. :P

I would be very grateful if someone could point me to my problem.


Crend
UMC Story Images — Story images for your campaign!
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: Crendgrim's Lua Thread

Post by Anonymissimus »

I don't see a "second call" do dbms. Well, what did it say why it isn't a wml table ?

If you get the "wml table inconsistently predicted" message from dbms it means my algorithm detected the wml table status (yes/no) differently from the engine which you should report then, I countercheck this every time.
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
Crendgrim
Moderator Emeritus
Posts: 1328
Joined: October 15th, 2010, 10:39 am
Location: Germany

Re: Crendgrim's Lua Thread

Post by Crendgrim »

I mean, if I use that tag two times it tells me "heey, you don't have a WML table, stupid" and then shows me some weird garbage of which I have no idea where it comes from...

Code: Select all

lua_var is of type table, value table: 0x7f2b26d0ffa0, length 2, but no WML table: table introducing subtag at [1] is not of the form {"tag_name", {}}:
{
    [1] = {
                  __varname = "cg_inventory[0]"
              },
    [2] = {
                  [1] = "item",
                  [2] = {
[...]
UMC Story Images — Story images for your campaign!
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: Crendgrim's Lua Thread

Post by Anonymissimus »

in the table at the unnamed field [1] you are in the "intermediate" level where named fields such as __varname= (a string) are not allowed (for a wml table). If an unnamed field appears in a wml table at the "main" level, it must hold a table, and that table must introduce a subtag by consisting of an unnamed field holding a string (the tagname) and another unnamed field holding a table. Within that table we're at "main" level again so named fields holding primitve types and unnamed ones holding tables (to introduce another subtag) are allowed. So that's what that error message means.
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
Luther
Posts: 128
Joined: July 28th, 2007, 5:19 pm
Location: USA

Re: Crendgrim's Lua Thread

Post by Luther »

My guess is that the proxy table needs special non-WML data in order to work, hence the incorrect element 1. Maybe you could use helper.get_variable_array instead of get_variable_proxy_array.

Ninja'd, but am I right?
Last edited by Luther on August 17th, 2011, 4:29 pm, edited 1 time in total.
Post Reply