Quick question

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

Moderator: Forum Moderators

Post Reply
User avatar
Pentarctagon
Project Manager
Posts: 5531
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Quick question

Post by Pentarctagon »

Is there a way to make a tag that can be used as part of the conditional in an [if] tag? In my case, it would be a [have_file] tag, so:

Code: Select all

[if]
  [have_file]
    path=$test
  [/have_file]
  [then]
...
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

Re: Quick question

Post by 8680 »

I don’t think so; would #ifhave work?
User avatar
Pentarctagon
Project Manager
Posts: 5531
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Quick question

Post by Pentarctagon »

It does, except then I can't use variables for the file path, which defeats the purpose.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

Re: Quick question

Post by 8680 »

Would this work?

Code: Select all

function wesnoth.wml_action.check_file_existence(cfg)
    local _, e = pcall(wesnoth.dofile, cfg.file)
    wesnoth.set_variable(
        cfg.variable or "file_exists",
    --  e == "cannot open " .. cfg.file .. ": No such file or directory" -- This would work for normal Lua dofile....
        e == "bad argument #1 to 'wesnoth.dofile' (file not found)"      -- This for wesnoth.dofile.
    )
end

Code: Select all

[check_file_existence]
    file="foo/bar/baz.cfg"
[/check_file_existence]
{IF_VAR "file_exists" boolean_equals yes (
    ...
)}
Edit: Fixed for wesnoth.dofile.
User avatar
Pentarctagon
Project Manager
Posts: 5531
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Quick question

Post by Pentarctagon »

pcall can only check lua files iirc. To clarify what I mean:

Code: Select all

  [event]
    name=preload
    first_time_only=no
    
    [lua]
      code=<<
      
      function wesnoth.wml_actions.have_file(file)
      found = wesnoth.have_file(file.path)
	  wesnoth.set_variable("found", found)
      end
      
      >>
    [/lua]
	
  [/event]
    
    [event]
      name=start
	  
	  {VARIABLE test "~add-ons/UMC_Music_Book_1/"} # exists
	  
        [have_file]
          path="$test"
        [/have_file]
      
      [if]
	  [variable]
	  name=found
	  equals="yes"
	  [/variable]
        [then]
          [message]
            speaker=narrator
            message="1"
          [/message]
        [/then]
        [else]
          [message]
            speaker=narrator
            message="0"
          [/message]
        [/else]
      [/if]
	  
	  {VARIABLE test "~add-ons/UMC_Music_Book_11/"} # doesn't exist
	  
        [have_file]
          path="$test"
        [/have_file]

      [if]
	  [variable]
	  name=found
	  equals="yes"
	  [/variable]
        [then]
          [message]
            speaker=narrator
            message="1"
          [/message]
        [/then]
        [else]
          [message]
            speaker=narrator
            message="0"
          [/message]
        [/else]
      [/if]
    
  [/event]
This is the code I was testing with. Everything works, I was just wondering if I could somehow put [have_file] in the [if] tag instead of setting a variable and checking that.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

Re: Quick question

Post by 8680 »

I didn’t know about wesnoth.have_file. I was relying on wesnoth.dofile (not pcall, that only catches the error) returning a distinct error when the file doesn’t exist. Which, now that I think about it, wouldn’t work for Lua files. (Edit: And I used == where I should have used ~=.)

Edit: This?

Code: Select all

local helper = wesnoth.require "lua/helper.lua"
function wesnoth.wml_action.if_have(cfg)
    local t, e = helper.get_child(cfg, "then"), helper.get_child(cfg, "else")
    if wesnoth.have_file(cfg.file or
        helper.wml_error "[if_have] missing required file= attribute")
    then
        if t then
            wesnoth.wml_actions.command(t)
        end
    elseif e then
        wesnoth.wml_actions.command(e)
    end
end

Code: Select all

[if_have]
    file="..."
    ## [then] and [else] both optional.
    [then]
        ...
    [/then]
    [else]
        ...
    [/else]
[/if_have]
Last edited by 8680 on December 15th, 2012, 5:23 pm, edited 1 time in total.
User avatar
Pentarctagon
Project Manager
Posts: 5531
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Quick question

Post by Pentarctagon »

I was aiming for the syntax in the OP, but this seems to work as well, thanks :)
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: Quick question

Post by Anonymissimus »

E_H appears to have written wesnoth.have_file. I can't find it in the wiki, but its code is there.
Since lua is run from events in networked multiplayer, this function probably checks independently on each client for the existence of the file. Using it in combination with wesnoth.synchronize_choice to transfer the result of the query from each of the clients when they are currently active to all of the currently inactive ones looks like they way it should be used.
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: Quick question

Post by Elvish_Hunter »

Anonymissimus wrote:E_H appears to have written wesnoth.have_file. I can't find it in the wiki, but its code is there.
Yes, I wrote it by taking the preprocessor code used in the #ifhave directive. It is documented here: http://wiki.wesnoth.org/LuaWML:Misc#wesnoth.have_file , but for some reason wasn't in the LuaWML page. It's fixed now.
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
Pentarctagon
Project Manager
Posts: 5531
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Quick question

Post by Pentarctagon »

It is a little misleading though. It says it follows the same rules as #ifhave, but it can use variables while #ifhave can't.

Also, I don't suppose there's a way to get it to be able to check core as well?
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: Quick question

Post by Anonymissimus »

Pentarctagon wrote:Also, I don't suppose there's a way to get it to be able to check core as well?
Reading the code a little, it should work as well.

EDIT
yes:
dbms(wesnoth.have_file("lua/helper.lua"))
gives true

Why do you want to check core ? Everything in core should be installed under whatever configuration or system the user has. If he has BfW at all.
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
Pentarctagon
Project Manager
Posts: 5531
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Quick question

Post by Pentarctagon »

I'm trying to check core, since in the add-on you can type in a music file to play and it could be in either core or from an add-on, but there's no way to know which.

A path like "~add-ons/UMC_Music_Book_1/music/snowfall.ogg" gives true, while "~data/core/music/victory.ogg" and any variations of that always give false.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

Re: Quick question

Post by 8680 »

Try "core/music/victory.ogg".
User avatar
Pentarctagon
Project Manager
Posts: 5531
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Quick question

Post by Pentarctagon »

It was the tilde... :annoyed:
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
Post Reply