How to get a list of all .dat files in ./data/maps/

Started by froggy77, August 02, 2016, 07:10:19 PM

Previous topic - Next topic
Hello,

I would like to get a list of all .dat files in ./data/maps/

e.g.:
./data/maps/cave_1f.dat ./data/maps/cave_2f.dat
./data/maps/inside_store.dat
./data/maps/library.dat
./data/maps/lost_woods.dat
./data/maps/outside_store.dat
./data/maps/outside_west.dat
./data/maps/shop.dat
./data/maps/test_map.dat
./data/maps/water_temple_1f.dat
./data/maps/water_temple_2f.dat
./data/maps/water_temple_final_room.dat
I found out a solution but it's quite complicated.
How would you do?

Found this at StackOverflow

http://stackoverflow.com/questions/30762476/how-to-read-a-bunch-of-files-in-a-directory-in-lua

Code (lua) Select
dirname = '.'
f = io.popen('ls ' .. dirname)
for name in f:lines() do print(name) end


Maybe this should help  :P

It opens a temporary external window whose display is very fast. The command (ls, dir, ...) can differ from the  OS.
This will be even more complicated than my solution.

I read the ./data/project_db.dat and create a table from this.

Code (LUA) Select

local function create_table_with_maps_id_from(file)

    local f = io.output (io.open (file, "r"))
    local tbl = {}
    local count = 1
    for line in io.lines(file) do
        if string.sub(line, 0, 3) == "map" then
            local pos = string.find(line, "\",") - 1
            local map_id = string.sub(line, 12, pos)
            tbl[count] = map_id
            count = count + 1
        end
    end
    f:close()
    return tbl
end

local project_db = "./data/project_db.dat"
local t_maps_id = create_table_with_maps_id_from(project_db)
for _, map_id in ipairs(t_maps_id) do
    local file = "./data/maps/" .. map_id .. ".dat"
    print(file)
end


If there is a solution with an internal Solarus command, it would be nice.
Thank you for io.popen that I did not know.

There are currently no functions to get the list of resources (too bad, because it should be easy to do). I just opened an issue: https://github.com/christopho/solarus/issues/959

For now, your idea is a good idea: read project_db.dat. But if you do so, use the sol.file API because you cannot be sure that "./data/project_db.dat" is the correct path. You don't know if the current directory is the one containing the quest. Maybe it is the case on your machine, but it won't be the case of users who run the Solarus launcher for example. Furthermore, it is supposed to be possible to play with a data.solarus archive instead of a regular data directory. Fortunately, the sol.file API takes care of all this for you. Basically, whenever you would want to use io.open(), just use sol.file.open instead.

An easier solution is to load the project_db.dat file as a Lua script, because its syntax is actually valid Lua :) This makes the parsing much easier. For example, I use this trick to parse map data files to implement the minimap of dungeons in order to locate treasure chests. Similarly, you would do that with sol.file.load_file() as a replacement of loadfile(), and use setfenv() to provide your own definition of the possible calls.
However, since you already parsed the file manually, you probably don't need to do it like this if your solution already works.

Thank you Christopho. It works fine with your method (https://github.com/christopho/zelda_roth_se/blob/dev/data/scripts/lib/chest_loader.lua).
It seems you know well Lua and Solarus Engine.  ;D

Code (lua) Select

local function create_table_with_maps_id_from_project_db()

    local ids = {}
    -- Set up a special environment to load the project_db data file.
    local environment = {
        map = function(project_db_map)
            local id = project_db_map.id
            if id ~= nil then
                ids[#ids + 1] = id
            end
        end
    }
    -- Make this function a no-op (map()).
    setmetatable(environment, {
        __index = function()
        return function() end
    end
    })
    -- Load the project_db data file as Lua.
    local chunk = sol.main.load_file("project_db.dat")
    -- Apply our special environment.
    setfenv(chunk, environment)
    -- Run it.
    chunk()
    return ids
end

local t_maps_id = create_table_with_maps_id_from_project_db()
for _, map_id in ipairs(t_maps_id) do
    local file = "./data/maps/" .. map_id .. ".dat"
    print(file)
end