generated from your-land/yl_template
	Code cleanup and organization #4
@ -35,7 +35,7 @@ The `save_path` is relative to the directory of the world that's using this mod.
 | 
			
		||||
The yl_cinema mod provides the following API functions that can be called from your own mod:
 | 
			
		||||
 | 
			
		||||
```lua
 | 
			
		||||
success, msg, movielist = yl_cinema.listmovies(searchterm)
 | 
			
		||||
success, msg, movielist = yl_cinema.list_movies(searchterm)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Parameters:
 | 
			
		||||
@ -47,7 +47,7 @@ Returns:
 | 
			
		||||
- `movielist`: An unordered table of movie IDs in the format `{"id1","id7","id27","id3"}`. It may be empty `{}` if no movies were found.
 | 
			
		||||
 | 
			
		||||
```lua
 | 
			
		||||
success, movie = yl_cinema.showmovie(name, movie_id, target_player_name)
 | 
			
		||||
success, movie = yl_cinema.show_movie(name, movie_id, target_player_name)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Parameters:
 | 
			
		||||
@ -60,7 +60,7 @@ Returns:
 | 
			
		||||
- `movie`: A string containing an error message if `success` is false, or a table representing the movie if `success` is true.
 | 
			
		||||
 | 
			
		||||
```lua
 | 
			
		||||
success, msg = yl_cinema.getmovie(movie_id)
 | 
			
		||||
success, msg = yl_cinema.get_movie(movie_id)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Parameters:
 | 
			
		||||
@ -108,4 +108,4 @@ This mod is licensed under the MIT License.
 | 
			
		||||
 | 
			
		||||
## Dedication
 | 
			
		||||
 | 
			
		||||
This mod is dedicated to daydream, whose determined love for the movie Princess Bride willed this mod into existence.
 | 
			
		||||
This mod is dedicated to daydream, whose determined love for the movie Princess Bride willed this mod into existence.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										215
									
								
								api.lua
									
									
									
									
									
								
							
							
						
						
									
										215
									
								
								api.lua
									
									
									
									
									
								
							@ -0,0 +1,215 @@
 | 
			
		||||
function yl_cinema.warn(text)
 | 
			
		||||
    minetest.log("warning", "[yl_cinema] " .. text)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.action(text)
 | 
			
		||||
    minetest.log("action", "[yl_cinema] " .. text)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- JSON helpers
 | 
			
		||||
 | 
			
		||||
local parse_json
 | 
			
		||||
if minetest.global_exists("json_lua") then
 | 
			
		||||
    parse_json = _G.json_lua.json.decode
 | 
			
		||||
else
 | 
			
		||||
    parse_json = minetest.parse_json
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function read_json_file(path)
 | 
			
		||||
    local file = io.open(path, "r")
 | 
			
		||||
    if not file then
 | 
			
		||||
        return false, "Error opening file: " .. path
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local content = file:read("*all")
 | 
			
		||||
    file:close()
 | 
			
		||||
 | 
			
		||||
    if not content then
 | 
			
		||||
        return false, "Error reading file: " .. path
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return true, parse_json(content)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Media helpers
 | 
			
		||||
 | 
			
		||||
local function remove_invisible_folders(folder_list)
 | 
			
		||||
    local filtered_list = {}
 | 
			
		||||
 | 
			
		||||
    for _, folder in ipairs(folder_list) do
 | 
			
		||||
        if not string.find(folder, "^%.") then
 | 
			
		||||
            table.insert(filtered_list, folder)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return filtered_list or {}
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function path_of_image(movie_id, name)
 | 
			
		||||
    return yl_cinema.worldpath .. yl_cinema.settings.save_path .. DIR_DELIM .. movie_id .. DIR_DELIM .. "textures" ..
 | 
			
		||||
               DIR_DELIM .. name
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function mediacallback(name)
 | 
			
		||||
    local target_name = name or ""
 | 
			
		||||
    yl_cinema.action("mediacallback: File pushed to player " .. target_name)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function load_image(path)
 | 
			
		||||
    local options = {
 | 
			
		||||
        filepath = path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return minetest.dynamic_add_media(options, mediacallback)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- API
 | 
			
		||||
 | 
			
		||||
function yl_cinema.orderpages(a, b)
 | 
			
		||||
    return a.order < b.order
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.string_to_recipe(s)
 | 
			
		||||
    local recipe = string.split(s, ",", true)
 | 
			
		||||
    if #recipe ~= 9 then
 | 
			
		||||
        return false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return {{recipe[1], recipe[2], recipe[3]}, {recipe[4], recipe[5], recipe[6]}, {recipe[7], recipe[8], recipe[9]}}
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.path_of_movie(movie_id)
 | 
			
		||||
    return yl_cinema.worldpath .. yl_cinema.settings.save_path .. DIR_DELIM .. movie_id .. DIR_DELIM .. movie_id ..
 | 
			
		||||
               ".json"
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.get_movie(movie_id)
 | 
			
		||||
    return yl_cinema.movies[movie_id] or {}
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.load_images_of_movie(movie_id)
 | 
			
		||||
    local movie = yl_cinema.get_movie(movie_id)
 | 
			
		||||
    local loaded_count = 0
 | 
			
		||||
    local movie_files = movie.files or {}
 | 
			
		||||
 | 
			
		||||
    if type(movie_files) ~= "table" then return 0, "no files" end
 | 
			
		||||
 | 
			
		||||
    for _, file in ipairs(movie_files) do
 | 
			
		||||
        local path = path_of_image(movie_id, file)
 | 
			
		||||
        local success = load_image(path)
 | 
			
		||||
 | 
			
		||||
        if success then
 | 
			
		||||
            loaded_count = loaded_count + 1
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return loaded_count, #movie_files
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function load_movie(movie_id)
 | 
			
		||||
    local file_path = yl_cinema.path_of_movie(movie_id)
 | 
			
		||||
    local success, movie_data = read_json_file(file_path)
 | 
			
		||||
    local movie = "Error loading movie metadata from file " .. dump(file_path) .. ": " .. dump(movie_data)
 | 
			
		||||
 | 
			
		||||
    if success then
 | 
			
		||||
        movie = movie_data
 | 
			
		||||
    else
 | 
			
		||||
        yl_cinema.warn(movie)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return success, movie
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.load_movies(movies_directory)
 | 
			
		||||
    local movies = {}
 | 
			
		||||
    local loaded_count = 0
 | 
			
		||||
 | 
			
		||||
    local folders = minetest.get_dir_list(movies_directory, true)
 | 
			
		||||
    local movie_files = remove_invisible_folders(folders)
 | 
			
		||||
 | 
			
		||||
    for _, movie_id in ipairs(movie_files) do
 | 
			
		||||
        local success, movie = load_movie(movie_id)
 | 
			
		||||
        if success then
 | 
			
		||||
            movies[movie_id] = movie
 | 
			
		||||
            loaded_count = loaded_count + 1
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return movies, loaded_count, #movie_files
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.init_movies()
 | 
			
		||||
    local movie_save_path = yl_cinema.worldpath .. yl_cinema.settings.save_path
 | 
			
		||||
    local movies, loaded_count, total_count = yl_cinema.load_movies(movie_save_path)
 | 
			
		||||
 | 
			
		||||
    if loaded_count ~= total_count then
 | 
			
		||||
        yl_cinema.warn(loaded_count .. "/" .. total_count .. " movies loaded.")
 | 
			
		||||
    else
 | 
			
		||||
        yl_cinema.action(loaded_count .. "/" .. total_count .. " movies loaded.")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return movies
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.search_movies(movies, search_term)
 | 
			
		||||
    local results = {}
 | 
			
		||||
 | 
			
		||||
    for movie_id, movie in pairs(movies) do
 | 
			
		||||
        if string.match(movie_id, search_term) or string.match(movie.name, search_term) or
 | 
			
		||||
            string.match(movie.description, search_term) then
 | 
			
		||||
                local item_string = ""
 | 
			
		||||
                if movie.item == true then
 | 
			
		||||
                    item_string = "yes"
 | 
			
		||||
                end
 | 
			
		||||
 | 
			
		||||
                table.insert(results, {movie_id, movie.name, item_string or ""})
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if #results > 0 then
 | 
			
		||||
        return true, results
 | 
			
		||||
    else
 | 
			
		||||
        return false, results
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.list_movies(searchterm)
 | 
			
		||||
    return yl_cinema.search_movies(yl_cinema.movies, searchterm)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.load_all_movies()
 | 
			
		||||
    yl_cinema.movies = yl_cinema.init_movies()
 | 
			
		||||
 | 
			
		||||
    for movie_id, _ in pairs(yl_cinema.movies) do
 | 
			
		||||
        local loaded_count, total_count = yl_cinema.load_images_of_movie(movie_id)
 | 
			
		||||
        if loaded_count ~= total_count then
 | 
			
		||||
            yl_cinema.warn(loaded_count .. "/" .. total_count .. " images loaded for movie " .. movie_id)
 | 
			
		||||
        else
 | 
			
		||||
            yl_cinema.action(loaded_count .. "/" .. total_count .. " images loaded for movie " .. movie_id)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return true, "Done."
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.load(filename, ...)
 | 
			
		||||
    return read_json_file(filename, ...)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.get_movie_reel(movie_id)
 | 
			
		||||
    if yl_cinema.settings.enable_movieitems ~= true then
 | 
			
		||||
        return false, "Movie items not enabled"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if not yl_cinema.movies or not yl_cinema.movies[movie_id] then
 | 
			
		||||
        return false, "Cannot find movie_id"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local stack = ItemStack(yl_cinema.movie_item_name_written)
 | 
			
		||||
    local meta = stack:get_meta()
 | 
			
		||||
 | 
			
		||||
    meta:set_string("_yl_cinema_movie_id", movie_id)
 | 
			
		||||
    meta:set_string("description", movie_id)
 | 
			
		||||
 | 
			
		||||
    return true, stack
 | 
			
		||||
end
 | 
			
		||||
@ -1,11 +0,0 @@
 | 
			
		||||
local chatcommand_cmd = "movie_imprint"
 | 
			
		||||
local chatcommand_definition = {
 | 
			
		||||
    params = "<movie>", -- Short parameter description
 | 
			
		||||
    description = "Imprints the <movie> on the wielded reel", -- Full description
 | 
			
		||||
    privs = {
 | 
			
		||||
        [yl_cinema.settings.admin_priv] = true
 | 
			
		||||
    }, -- Require the "privs" privilege to run
 | 
			
		||||
    func = yl_cinema.cmd_movie_imprint
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
minetest.register_chatcommand(chatcommand_cmd, chatcommand_definition)
 | 
			
		||||
@ -1,11 +0,0 @@
 | 
			
		||||
local chatcommand_cmd = "movie_list"
 | 
			
		||||
local chatcommand_definition = {
 | 
			
		||||
    params = "[<searchstring>]", -- Short parameter description
 | 
			
		||||
    description = "Shows the whole movielist to you that match the <searchstring>, if given", -- Full description
 | 
			
		||||
    privs = {
 | 
			
		||||
        [yl_cinema.settings.admin_priv] = true
 | 
			
		||||
    }, -- Require the "privs" privilege to run
 | 
			
		||||
    func = yl_cinema.cmd_list_movies
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
minetest.register_chatcommand(chatcommand_cmd, chatcommand_definition)
 | 
			
		||||
@ -1,11 +0,0 @@
 | 
			
		||||
local chatcommand_cmd = "movie_reload"
 | 
			
		||||
local chatcommand_definition = {
 | 
			
		||||
    params = "[<movie_id>]", -- Short parameter description
 | 
			
		||||
    description = "Reload specific <movie_id> or all movies, but does not create movie reel items.",
 | 
			
		||||
    privs = {
 | 
			
		||||
        [yl_cinema.settings.admin_priv] = true
 | 
			
		||||
    },
 | 
			
		||||
    func = yl_cinema.cmd_movie_reload
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
minetest.register_chatcommand(chatcommand_cmd, chatcommand_definition)
 | 
			
		||||
@ -1,11 +0,0 @@
 | 
			
		||||
local chatcommand_cmd = "movie_show"
 | 
			
		||||
local chatcommand_definition = {
 | 
			
		||||
    params = "<name> <movie>", -- Short parameter description
 | 
			
		||||
    description = "Shows to the <player> the <movie>", -- Full description
 | 
			
		||||
    privs = {
 | 
			
		||||
        [yl_cinema.settings.admin_priv] = true
 | 
			
		||||
    }, -- Require the "privs" privilege to run
 | 
			
		||||
    func = yl_cinema.cmd_show_movie
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
minetest.register_chatcommand(chatcommand_cmd, chatcommand_definition)
 | 
			
		||||
@ -1,4 +0,0 @@
 | 
			
		||||
dofile(yl_cinema.modpath .. "chatcommand_movie_show.lua")
 | 
			
		||||
dofile(yl_cinema.modpath .. "chatcommand_movie_list.lua")
 | 
			
		||||
dofile(yl_cinema.modpath .. "chatcommand_movie_reload.lua")
 | 
			
		||||
dofile(yl_cinema.modpath .. "chatcommand_movie_imprint.lua")
 | 
			
		||||
							
								
								
									
										65
									
								
								chatcommands/movie_imprint.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								chatcommands/movie_imprint.lua
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,65 @@
 | 
			
		||||
if yl_cinema.settings.enable_movieitems ~= true then
 | 
			
		||||
    return
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function imprint_movie(name, movie_id)
 | 
			
		||||
    local pobj = minetest.get_player_by_name(name)
 | 
			
		||||
    if not pobj then
 | 
			
		||||
        return false, "Cannot find player"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local old_stack = pobj:get_wielded_item()
 | 
			
		||||
    if (not old_stack) or (old_stack:get_name() ~= yl_cinema.movie_item_name_empty) then
 | 
			
		||||
        return false, "Please wield an empty movie reel"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    -- Prepare new itemstack
 | 
			
		||||
    local got_reel, stack_or_err = yl_cinema.get_movie_reel(movie_id)
 | 
			
		||||
    if not got_reel then
 | 
			
		||||
        return false, stack_or_err
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    -- Replace or add
 | 
			
		||||
    if old_stack:get_count() == 1 then
 | 
			
		||||
        -- replace
 | 
			
		||||
        pobj:set_wielded_item(stack_or_err)
 | 
			
		||||
        return true, ""
 | 
			
		||||
    else
 | 
			
		||||
        -- can we add?
 | 
			
		||||
        local inv = pobj:get_inventory()
 | 
			
		||||
        local listname = "main"
 | 
			
		||||
 | 
			
		||||
        if not inv:room_for_item(listname, stack_or_err) then
 | 
			
		||||
            return false, "No space in inventory for new print."
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        -- remove old
 | 
			
		||||
        old_stack:take_item(1)
 | 
			
		||||
        pobj:set_wielded_item(old_stack)
 | 
			
		||||
        -- add new
 | 
			
		||||
        inv:add_item(listname, stack_or_err)
 | 
			
		||||
 | 
			
		||||
        return true, ""
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_chatcommand("movie_imprint", {
 | 
			
		||||
    params = "<movie>", -- Short parameter description
 | 
			
		||||
    description = "Imprints the <movie> on the wielded reel", -- Full description
 | 
			
		||||
    privs = {
 | 
			
		||||
        [yl_cinema.settings.admin_priv] = true
 | 
			
		||||
    }, -- Require the "privs" privilege to run
 | 
			
		||||
    func = function(name, param)
 | 
			
		||||
        local args = string.split(param, " ")
 | 
			
		||||
 | 
			
		||||
        if (#args > 1) then
 | 
			
		||||
            return false, "Usage: /movie_imprint [<movie_id>]"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        local movie_id = args[1] or ""
 | 
			
		||||
 | 
			
		||||
        yl_cinema.action("Player " .. name .. " imprints movie " .. movie_id)
 | 
			
		||||
 | 
			
		||||
        return imprint_movie(name, movie_id)
 | 
			
		||||
    end
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										67
									
								
								chatcommands/movie_list.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								chatcommands/movie_list.lua
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,67 @@
 | 
			
		||||
local function format_table(t)
 | 
			
		||||
    -- Format of t must be {{row1,row2,row3, ...},{row1,row2,row3, ...},...}
 | 
			
		||||
    local blanks_between_rows = 3
 | 
			
		||||
    local max_row_length = {}
 | 
			
		||||
    for linenumber = 1, #t do
 | 
			
		||||
        for rownumber = 1, #t[linenumber] do
 | 
			
		||||
            local row_length = #tostring(t[linenumber][rownumber])
 | 
			
		||||
            if (max_row_length[rownumber] or 0) < row_length then
 | 
			
		||||
                max_row_length[rownumber] = row_length
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local ret = {}
 | 
			
		||||
 | 
			
		||||
    for linenumber = 1, #t do
 | 
			
		||||
        local line_s = ""
 | 
			
		||||
        for rownumber = 1, #t[linenumber] do
 | 
			
		||||
            local text = t[linenumber][rownumber]
 | 
			
		||||
            local text_length = #tostring(text)
 | 
			
		||||
            local add_blanks = max_row_length[rownumber] - text_length
 | 
			
		||||
            local newtext = t[linenumber][rownumber]
 | 
			
		||||
            for add = 1, (add_blanks + blanks_between_rows) do
 | 
			
		||||
                newtext = newtext .. " "
 | 
			
		||||
            end
 | 
			
		||||
            line_s = line_s .. newtext
 | 
			
		||||
        end
 | 
			
		||||
        table.insert(ret,line_s)
 | 
			
		||||
    end
 | 
			
		||||
    return table.concat(ret, "\n")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_chatcommand("movie_list", {
 | 
			
		||||
    params = "[<searchstring>]", -- Short parameter description
 | 
			
		||||
    description = "Shows the whole movielist to you that match the <searchstring>, if given", -- Full description
 | 
			
		||||
    privs = {
 | 
			
		||||
        [yl_cinema.settings.admin_priv] = true
 | 
			
		||||
    }, -- Require the "privs" privilege to run
 | 
			
		||||
 | 
			
		||||
    func = function(name, param)
 | 
			
		||||
        local args = string.split(param, " ")
 | 
			
		||||
 | 
			
		||||
        if (#args > 1) then
 | 
			
		||||
            return false, "Usage: /listmovies [<searchstring>]"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        local searchterm = args[1] or ""
 | 
			
		||||
 | 
			
		||||
        yl_cinema.action("Player " .. name .. " searches for movie " .. searchterm)
 | 
			
		||||
 | 
			
		||||
        local display_table = {{"movie_id","name","itemstring"}}
 | 
			
		||||
 | 
			
		||||
        local success, t = yl_cinema.list_movies(searchterm)
 | 
			
		||||
 | 
			
		||||
        for _,movies in ipairs(t) do
 | 
			
		||||
            table.insert(display_table, movies)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        local nice_format = format_table(display_table)
 | 
			
		||||
 | 
			
		||||
        if success then
 | 
			
		||||
            return true, nice_format
 | 
			
		||||
        else
 | 
			
		||||
            return false, "No movies matching your criteria were found."
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										20
									
								
								chatcommands/movie_reload.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								chatcommands/movie_reload.lua
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
minetest.register_chatcommand("movie_reload", {
 | 
			
		||||
    params = "[<movie_id>]", -- Short parameter description
 | 
			
		||||
    description = "Reload specific <movie_id> or all movies, but does not create movie reel items.",
 | 
			
		||||
    privs = {
 | 
			
		||||
        [yl_cinema.settings.admin_priv] = true
 | 
			
		||||
    },
 | 
			
		||||
    func = function(name, param)
 | 
			
		||||
        local args = string.split(param, " ")
 | 
			
		||||
 | 
			
		||||
        if (#args >= 2) then
 | 
			
		||||
            return false, "Usage: /movie_reload [<movie_id>]"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        local movie_id = args[1] or ""
 | 
			
		||||
 | 
			
		||||
        yl_cinema.action("Player " .. name .. " reloads movie " .. movie_id)
 | 
			
		||||
 | 
			
		||||
        return yl_cinema.load_all_movies()
 | 
			
		||||
    end
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										31
									
								
								chatcommands/movie_show.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								chatcommands/movie_show.lua
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
			
		||||
minetest.register_chatcommand("movie_show", {
 | 
			
		||||
    params = "<name> <movie>", -- Short parameter description
 | 
			
		||||
    description = "Shows to the <player> the <movie>", -- Full description
 | 
			
		||||
    privs = {
 | 
			
		||||
        [yl_cinema.settings.admin_priv] = true
 | 
			
		||||
    }, -- Require the "privs" privilege to run
 | 
			
		||||
 | 
			
		||||
    func = function(name, param)
 | 
			
		||||
        local args = string.split(param, " ")
 | 
			
		||||
 | 
			
		||||
        if (#args ~= 2) then
 | 
			
		||||
            return false, "Usage: /showmovie <playername> <movie>"
 | 
			
		||||
        end
 | 
			
		||||
        if not minetest.get_player_by_name(args[1]) then
 | 
			
		||||
            return false, "Player not online"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        local target_player_name = args[1] or ""
 | 
			
		||||
        local movie_id = args[2] or ""
 | 
			
		||||
 | 
			
		||||
        yl_cinema.action("Player " .. name .. " shows movie " .. movie_id .. " to " .. target_player_name)
 | 
			
		||||
 | 
			
		||||
        local success, msg = yl_cinema.show_movie(movie_id, target_player_name)
 | 
			
		||||
 | 
			
		||||
        if success then
 | 
			
		||||
            return true, msg
 | 
			
		||||
        else
 | 
			
		||||
            return false, msg
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
})
 | 
			
		||||
@ -1,7 +0,0 @@
 | 
			
		||||
yl_cinema.dependencies = {}
 | 
			
		||||
 | 
			
		||||
if minetest.get_modpath("json_lua") and json_lua then
 | 
			
		||||
    yl_cinema.dependencies.json = json_lua.json
 | 
			
		||||
else
 | 
			
		||||
    yl_cinema.dependencies.json = yl_cinema.error
 | 
			
		||||
end
 | 
			
		||||
@ -1,4 +0,0 @@
 | 
			
		||||
dofile(yl_cinema.modpath .. "feature_bigscreen_items.lua")
 | 
			
		||||
dofile(yl_cinema.modpath .. "feature_bigscreen_entity.lua")
 | 
			
		||||
dofile(yl_cinema.modpath .. "feature_bigscreen_crafting.lua")
 | 
			
		||||
dofile(yl_cinema.modpath .. "feature_bigscreen_integration.lua")
 | 
			
		||||
@ -1,16 +0,0 @@
 | 
			
		||||
if (yl_cinema.settings.enable_bigscreen and (yl_cinema.settings.enable_bigscreen == true) and
 | 
			
		||||
    yl_cinema.settings.enable_craft_bigscreen and (yl_cinema.settings.enable_craft_bigscreen == true)) then
 | 
			
		||||
 | 
			
		||||
    local recipe = yl_cinema.string_to_recipe(yl_cinema.settings.enable_craft_bigscreen_recipe)
 | 
			
		||||
 | 
			
		||||
    if type(recipe) == "table" then
 | 
			
		||||
        minetest.register_craft({
 | 
			
		||||
            type = "shaped",
 | 
			
		||||
            output = "yl_cinema:bigscreen_base",
 | 
			
		||||
            recipe = recipe
 | 
			
		||||
        })
 | 
			
		||||
    else
 | 
			
		||||
        yl_cinema.warn("Cannot register crafting recipe for bigscreen: " ..
 | 
			
		||||
                           dump(yl_cinema.settings.enable_craft_bigscreen_recipe))
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
@ -1,10 +0,0 @@
 | 
			
		||||
 | 
			
		||||
if minetest.get_modpath("mesecons_mvps") then
 | 
			
		||||
    mesecon.register_mvps_stopper(yl_cinema.bigscreen_block_name)
 | 
			
		||||
    mesecon.register_mvps_stopper(yl_cinema.flatscreen_block_name)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
if minetest.get_modpath("replacer") and replacer and replacer.blacklist then
 | 
			
		||||
    replacer.blacklist[yl_cinema.bigscreen_block_name] = true
 | 
			
		||||
    replacer.blacklist[yl_cinema.flatscreen_block_name] = true
 | 
			
		||||
end
 | 
			
		||||
@ -1,3 +1,23 @@
 | 
			
		||||
-- TODO: Move bigscreen node here
 | 
			
		||||
-- Craft the bigscreen
 | 
			
		||||
 | 
			
		||||
if (yl_cinema.settings.enable_bigscreen and (yl_cinema.settings.enable_bigscreen == true) and
 | 
			
		||||
    yl_cinema.settings.enable_craft_bigscreen and (yl_cinema.settings.enable_craft_bigscreen == true)) then
 | 
			
		||||
 | 
			
		||||
    local bigscreen_recipe = yl_cinema.string_to_recipe(yl_cinema.settings.enable_craft_bigscreen_recipe)
 | 
			
		||||
 | 
			
		||||
    if type(bigscreen_recipe) == "table" then
 | 
			
		||||
        minetest.register_craft({
 | 
			
		||||
            type = "shaped",
 | 
			
		||||
            output = "yl_cinema:bigscreen_base",
 | 
			
		||||
            recipe = bigscreen_recipe
 | 
			
		||||
        })
 | 
			
		||||
    else
 | 
			
		||||
        yl_cinema.warn("Cannot register crafting recipe for bigscreen: " ..
 | 
			
		||||
                           dump(yl_cinema.settings.enable_craft_bigscreen_recipe))
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
if yl_cinema.settings.enable_movieitems ~= true then
 | 
			
		||||
    return
 | 
			
		||||
end
 | 
			
		||||
@ -10,6 +30,7 @@ local movie_item_definition_empty = {
 | 
			
		||||
        movie = 1,
 | 
			
		||||
        media = 1
 | 
			
		||||
    },
 | 
			
		||||
    description = "Blank Movie Reel",
 | 
			
		||||
    inventory_image = "yl_cinema_icon_movie_empty_inv.png",
 | 
			
		||||
    wield_image = "yl_cinema_icon_movie_empty_inv.png",
 | 
			
		||||
}
 | 
			
		||||
@ -25,6 +46,7 @@ local movie_item_definition = {
 | 
			
		||||
        not_in_creative_inventory = 1,
 | 
			
		||||
        media = 1
 | 
			
		||||
    },
 | 
			
		||||
    description = "[UNLABELED MOVIE PRINT]", -- This should get overridden
 | 
			
		||||
    inventory_image = "yl_cinema_icon_movie_inv.png",
 | 
			
		||||
    wield_image = "yl_cinema_icon_movie_inv.png",
 | 
			
		||||
    stack_max = 1,
 | 
			
		||||
@ -34,13 +56,13 @@ minetest.register_craftitem(yl_cinema.movie_item_name_written, movie_item_defini
 | 
			
		||||
 | 
			
		||||
-- Craft the empty reel
 | 
			
		||||
 | 
			
		||||
local recipe = yl_cinema.string_to_recipe(yl_cinema.settings.enable_craft_moviereel_recipe)
 | 
			
		||||
local reel_recipe = yl_cinema.string_to_recipe(yl_cinema.settings.enable_craft_moviereel_recipe)
 | 
			
		||||
 | 
			
		||||
if type(recipe) == "table" then
 | 
			
		||||
if type(reel_recipe) == "table" then
 | 
			
		||||
    minetest.register_craft({
 | 
			
		||||
        type = "shaped",
 | 
			
		||||
        output = yl_cinema.movie_item_name_empty,
 | 
			
		||||
        recipe = recipe
 | 
			
		||||
        recipe = reel_recipe
 | 
			
		||||
    })
 | 
			
		||||
else
 | 
			
		||||
    yl_cinema.warn("Cannot register crafting recipe for Reel Item: " ..
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										125
									
								
								feature_formspec.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								feature_formspec.lua
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,125 @@
 | 
			
		||||
local F = minetest.formspec_escape
 | 
			
		||||
yl_cinema.watching = {}
 | 
			
		||||
 | 
			
		||||
local function watches(playername, movie_id)
 | 
			
		||||
    yl_cinema.watching[playername] = movie_id
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function watched_by(playername)
 | 
			
		||||
    return yl_cinema.watching[playername] or ""
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function stops_watching(player)
 | 
			
		||||
    local playername = player:get_player_name()
 | 
			
		||||
    yl_cinema.watching[playername] = nil
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function get_movieformspec(movie_id, pagenum)
 | 
			
		||||
    local movie = yl_cinema.get_movie(movie_id)
 | 
			
		||||
    local screen_width = 12
 | 
			
		||||
    local screen_height = 6.75
 | 
			
		||||
    local screensize = screen_width .. "," .. 6.75
 | 
			
		||||
 | 
			
		||||
    local formspec = {}
 | 
			
		||||
    table.insert(formspec, "formspec_version[4]size[" .. screensize .. "]bgcolor[#000000]")
 | 
			
		||||
 | 
			
		||||
    if (not movie) or (not pagenum) then
 | 
			
		||||
        warn("Some error happened. movie=" .. dump(movie) .. ", page=" .. dump(pagenum))
 | 
			
		||||
        table.insert(formspec, "[0.5,0.5;Some Error happened.]")
 | 
			
		||||
        return table.concat(formspec, "")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if pagenum == 0 then
 | 
			
		||||
        table.insert(formspec, "background[0,0;" .. screensize .. ";" .. (F(movie.title_texture) or "") .. ";true]")
 | 
			
		||||
        table.insert(formspec, "label[0.5,0.5;" .. (F(movie.name) or "") .. "]")
 | 
			
		||||
        table.insert(formspec, "textarea[0.5,1.5;" .. screensize .. ";;" .. (F(movie.description) or "") .. ";]")
 | 
			
		||||
    else
 | 
			
		||||
        local page = movie.pages[pagenum]
 | 
			
		||||
 | 
			
		||||
        if not page then
 | 
			
		||||
            warn("Page empty = " .. dump(page))
 | 
			
		||||
            return ""
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        table.insert(formspec, "background[0,0;" .. screensize .. ";" .. (F(page.texture) or "") .. ";true]")
 | 
			
		||||
        table.insert(formspec, "label[" .. (F(page.captionposx) or 0) .. "," .. (F(page.captionposy) or 0) .. ";" ..
 | 
			
		||||
            (F(page.caption) or "") .. "]")
 | 
			
		||||
 | 
			
		||||
        if pagenum == #movie.pages then
 | 
			
		||||
            table.insert(formspec, "button[3," .. (F(screen_height) - 1) .. ";2,1;replay;Replay]")
 | 
			
		||||
            table.insert(formspec, "button_exit[6," .. (F(screen_height) - 1) .. ";2,1;exit;Exit]")
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return table.concat(formspec, "")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function showpage(target_player_name, movie_id, pagenum)
 | 
			
		||||
    if not minetest.get_player_by_name(target_player_name) then
 | 
			
		||||
        return
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if watched_by(target_player_name) == "" then
 | 
			
		||||
        return
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local formspec = get_movieformspec(movie_id, pagenum)
 | 
			
		||||
 | 
			
		||||
    local movie = yl_cinema.get_movie(movie_id)
 | 
			
		||||
    local pages = movie.pages
 | 
			
		||||
 | 
			
		||||
    if pagenum <= #pages then
 | 
			
		||||
        table.sort(pages, yl_cinema.orderpages)
 | 
			
		||||
 | 
			
		||||
        local page = pages[pagenum] or {}
 | 
			
		||||
        local delay = page.duration or 3
 | 
			
		||||
        local nextpage = pagenum + 1
 | 
			
		||||
 | 
			
		||||
        minetest.after(delay, showpage, target_player_name, movie_id, nextpage)
 | 
			
		||||
 | 
			
		||||
        watches(target_player_name, movie_id)
 | 
			
		||||
 | 
			
		||||
        minetest.show_formspec(target_player_name, "yl_cinema:movie", formspec)
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
    if formname ~= "yl_cinema:movie" then
 | 
			
		||||
        return
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local playername = player:get_player_name()
 | 
			
		||||
 | 
			
		||||
    if fields.exit or fields.quit then
 | 
			
		||||
        stops_watching(player)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if player and fields.replay then
 | 
			
		||||
        local movie_id = watched_by(playername)
 | 
			
		||||
        showpage(player:get_player_name(), movie_id, 0)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return true
 | 
			
		||||
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
function yl_cinema.show_movie(movie_id, target_player_name)
 | 
			
		||||
    local pagenum = 0
 | 
			
		||||
    if not next(yl_cinema.get_movie(movie_id)) then
 | 
			
		||||
        return false, "Movie " .. movie_id .. " not found."
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    watches(target_player_name, movie_id)
 | 
			
		||||
 | 
			
		||||
    -- Start to show a movie
 | 
			
		||||
    if minetest.get_player_by_name(target_player_name) then
 | 
			
		||||
        showpage(target_player_name, movie_id, pagenum)
 | 
			
		||||
        return true, "Movie " .. movie_id .. " started for " .. target_player_name
 | 
			
		||||
    else
 | 
			
		||||
        return false, "Player " .. target_player_name .. " not found."
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_leaveplayer(stops_watching)
 | 
			
		||||
minetest.register_on_dieplayer(stops_watching)
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
dofile(yl_cinema.modpath .. "feature_bigscreen.lua")
 | 
			
		||||
							
								
								
									
										37
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								init.lua
									
									
									
									
									
								
							@ -21,14 +21,39 @@ yl_cinema.information.name = "yl_cinema"
 | 
			
		||||
yl_cinema.information.source = "https://gitea.your-land.de/your-land/yl_cinema"
 | 
			
		||||
yl_cinema.information.additional = "This mod implements #9 of the Small Tasks: A way to display pictures to a player."
 | 
			
		||||
 | 
			
		||||
dofile(yl_cinema.modpath .. "dependencies.lua")
 | 
			
		||||
-- Load configuration
 | 
			
		||||
dofile(yl_cinema.modpath .. "config.lua")
 | 
			
		||||
dofile(yl_cinema.modpath .. "setup.lua")
 | 
			
		||||
dofile(yl_cinema.modpath .. "internal.lua")
 | 
			
		||||
 | 
			
		||||
-- Create movie path if needed
 | 
			
		||||
minetest.mkdir(yl_cinema.worldpath .. DIR_DELIM .. yl_cinema.settings.save_path)
 | 
			
		||||
 | 
			
		||||
-- Set up API
 | 
			
		||||
dofile(yl_cinema.modpath .. "api.lua")
 | 
			
		||||
dofile(yl_cinema.modpath .. "initialize.lua")
 | 
			
		||||
dofile(yl_cinema.modpath .. "features.lua")
 | 
			
		||||
dofile(yl_cinema.modpath .. "chatcommands.lua")
 | 
			
		||||
 | 
			
		||||
-- Initialize features
 | 
			
		||||
dofile(yl_cinema.modpath .. "feature_bigscreen_items.lua")
 | 
			
		||||
dofile(yl_cinema.modpath .. "feature_bigscreen_entity.lua")
 | 
			
		||||
dofile(yl_cinema.modpath .. "feature_formspec.lua")
 | 
			
		||||
 | 
			
		||||
if minetest.get_modpath("mesecons_mvps") then
 | 
			
		||||
    mesecon.register_mvps_stopper(yl_cinema.bigscreen_block_name)
 | 
			
		||||
    mesecon.register_mvps_stopper(yl_cinema.flatscreen_block_name)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
if minetest.get_modpath("replacer") and replacer and replacer.blacklist then
 | 
			
		||||
    replacer.blacklist[yl_cinema.bigscreen_block_name] = true
 | 
			
		||||
    replacer.blacklist[yl_cinema.flatscreen_block_name] = true
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Register chatcommands
 | 
			
		||||
for _, filename in ipairs(minetest.get_dir_list(yl_cinema.modpath .. "/chatcommands", false)) do
 | 
			
		||||
    if filename:sub(-4) == ".lua" then
 | 
			
		||||
        dofile(yl_cinema.modpath .. "/chatcommands/" .. filename)
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Load movies
 | 
			
		||||
minetest.after(0, yl_cinema.load_all_movies)
 | 
			
		||||
 | 
			
		||||
local mod_end_time = (minetest.get_us_time() - mod_start_time) / 1000000
 | 
			
		||||
minetest.log("action", "[MOD] yl_cinema loaded in [" .. mod_end_time .. "s]")
 | 
			
		||||
 | 
			
		||||
@ -1,6 +0,0 @@
 | 
			
		||||
 | 
			
		||||
local function run_each_serverstart()
 | 
			
		||||
    minetest.after(0,yl_cinema.load_all_movies)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
run_each_serverstart()
 | 
			
		||||
							
								
								
									
										519
									
								
								internal.lua
									
									
									
									
									
								
							
							
						
						
									
										519
									
								
								internal.lua
									
									
									
									
									
								
							@ -1,519 +0,0 @@
 | 
			
		||||
-- The functions and variables in this file are only for use in the mod itself.
 | 
			
		||||
-- Those that do real work should be local and wrapped in public functions
 | 
			
		||||
-- Minetest connector
 | 
			
		||||
local json = yl_cinema.dependencies.json
 | 
			
		||||
local F = minetest.formspec_escape
 | 
			
		||||
yl_cinema.watching = {}
 | 
			
		||||
 | 
			
		||||
local function warn(text)
 | 
			
		||||
    minetest.log("warning", "[yl_cinema] " .. text)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function action(text)
 | 
			
		||||
    minetest.log("action", "[yl_cinema] " .. text)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- JSON decoder
 | 
			
		||||
local parse_json
 | 
			
		||||
if json == yl_cinema.error or json == nil then
 | 
			
		||||
    local function parse_json(json_str)
 | 
			
		||||
        return minetest.parse_json(json_str)
 | 
			
		||||
    end
 | 
			
		||||
else
 | 
			
		||||
    local function parse_json(json_str)
 | 
			
		||||
        return json.decode(json_str)
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Initialize files
 | 
			
		||||
 | 
			
		||||
local function get_files_in_directory(folderpath)
 | 
			
		||||
    return minetest.get_dir_list(folderpath, true)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- internal functions
 | 
			
		||||
 | 
			
		||||
local function format_table(t)
 | 
			
		||||
    -- Format of t must be {{row1,row2,row3, ...},{row1,row2,row3, ...},...}
 | 
			
		||||
    local blanks_between_rows = 3
 | 
			
		||||
    local max_row_length = {}
 | 
			
		||||
    for linenumber = 1, #t do
 | 
			
		||||
        for rownumber = 1, #t[linenumber] do
 | 
			
		||||
            local row_length = #tostring(t[linenumber][rownumber])
 | 
			
		||||
            if (max_row_length[rownumber] or 0) < row_length then
 | 
			
		||||
                max_row_length[rownumber] = row_length
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local ret = {}
 | 
			
		||||
 | 
			
		||||
    for linenumber = 1, #t do
 | 
			
		||||
        local line_s = ""
 | 
			
		||||
        for rownumber = 1, #t[linenumber] do
 | 
			
		||||
            local text = t[linenumber][rownumber]
 | 
			
		||||
            local text_length = #tostring(text)
 | 
			
		||||
            local add_blanks = max_row_length[rownumber] - text_length
 | 
			
		||||
            local newtext = t[linenumber][rownumber]
 | 
			
		||||
            for add = 1, (add_blanks + blanks_between_rows) do
 | 
			
		||||
                newtext = newtext .. " "
 | 
			
		||||
            end
 | 
			
		||||
            line_s = line_s .. newtext
 | 
			
		||||
        end
 | 
			
		||||
        table.insert(ret,line_s)
 | 
			
		||||
    end
 | 
			
		||||
    return table.concat(ret, "\n")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function remove_invisible_folders(folder_list)
 | 
			
		||||
    local filtered_list = {}
 | 
			
		||||
    for _, folder in ipairs(folder_list) do
 | 
			
		||||
        if not string.find(folder, "^%.") then
 | 
			
		||||
            table.insert(filtered_list, folder)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    return filtered_list or {}
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function watches(playername, movie_id)
 | 
			
		||||
    yl_cinema.watching[playername] = movie_id
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function watched_by(playername)
 | 
			
		||||
    return yl_cinema.watching[playername] or ""
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function stops_watching(player)
 | 
			
		||||
    local playername = player:get_player_name()
 | 
			
		||||
    yl_cinema.watching[playername] = nil
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function orderpages(a, b)
 | 
			
		||||
    return a.order < b.order
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function mediacallback(name)
 | 
			
		||||
    local target_name = name or ""
 | 
			
		||||
    action("mediacallback: File pushed to player " .. target_name)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function string_to_recipe(s)
 | 
			
		||||
    local recipe = string.split(s, ",",true)
 | 
			
		||||
    if #recipe ~= 9 then
 | 
			
		||||
        return false
 | 
			
		||||
    end
 | 
			
		||||
    return {{recipe[1], recipe[2], recipe[3]}, {recipe[4], recipe[5], recipe[6]}, {recipe[7], recipe[8], recipe[9]}}
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function path_of_movie(movie_id)
 | 
			
		||||
    return yl_cinema.worldpath .. yl_cinema.settings.save_path .. DIR_DELIM .. movie_id .. DIR_DELIM .. movie_id ..
 | 
			
		||||
               ".json"
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function path_of_image(movie_id, name)
 | 
			
		||||
    return yl_cinema.worldpath .. yl_cinema.settings.save_path .. DIR_DELIM .. movie_id .. DIR_DELIM .. "textures" ..
 | 
			
		||||
               DIR_DELIM .. name
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function read_json_file(path)
 | 
			
		||||
    local file = io.open(path, "r")
 | 
			
		||||
    if not file then
 | 
			
		||||
        return false, "Error opening file: " .. path
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local content = file:read("*all")
 | 
			
		||||
    file:close()
 | 
			
		||||
 | 
			
		||||
    if not content then
 | 
			
		||||
        return false, "Error reading file: " .. path
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return true, parse_json(content)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function get_movie(movie_id)
 | 
			
		||||
    return yl_cinema.movies[movie_id] or {}
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function load_image(path)
 | 
			
		||||
    local options = {
 | 
			
		||||
        filepath = path
 | 
			
		||||
    }
 | 
			
		||||
    return minetest.dynamic_add_media(options, mediacallback)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function load_images_of_movie(movie_id)
 | 
			
		||||
    local movie = get_movie(movie_id)
 | 
			
		||||
    local loaded_count = 0
 | 
			
		||||
    local movie_files = movie.files or {}
 | 
			
		||||
 | 
			
		||||
    if type(movie_files) ~= "table" then return 0, "no files" end
 | 
			
		||||
 | 
			
		||||
    for _, file in ipairs(movie_files) do
 | 
			
		||||
        local path = path_of_image(movie_id, file)
 | 
			
		||||
        local success = load_image(path)
 | 
			
		||||
        if success then
 | 
			
		||||
            loaded_count = loaded_count + 1
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return loaded_count, #movie_files
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function load_movie(movie_id)
 | 
			
		||||
    local file_path = path_of_movie(movie_id)
 | 
			
		||||
    local success, movie_data = read_json_file(file_path)
 | 
			
		||||
    local movie = "Error loading movie metadata from file " .. dump(file_path) .. ": " .. dump(movie_data)
 | 
			
		||||
    if success then
 | 
			
		||||
        movie = movie_data
 | 
			
		||||
    else
 | 
			
		||||
        warn(movie)
 | 
			
		||||
    end
 | 
			
		||||
    return success, movie
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function load_movies(movies_directory)
 | 
			
		||||
    local movies = {}
 | 
			
		||||
    local loaded_count = 0
 | 
			
		||||
 | 
			
		||||
    local folders = get_files_in_directory(movies_directory)
 | 
			
		||||
    local movie_files = remove_invisible_folders(folders)
 | 
			
		||||
    for _, movie_id in ipairs(movie_files) do
 | 
			
		||||
        local success, movie = load_movie(movie_id)
 | 
			
		||||
        if success then
 | 
			
		||||
            movies[movie_id] = movie
 | 
			
		||||
            loaded_count = loaded_count + 1
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return movies, loaded_count, #movie_files
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.init_movies()
 | 
			
		||||
    local movie_save_path = yl_cinema.worldpath .. yl_cinema.settings.save_path
 | 
			
		||||
    local movies, loaded_count, total_count = yl_cinema.load_movies(movie_save_path)
 | 
			
		||||
    if loaded_count ~= total_count then
 | 
			
		||||
        yl_cinema.warn(loaded_count .. "/" .. total_count .. " movies loaded.")
 | 
			
		||||
    else
 | 
			
		||||
        yl_cinema.action(loaded_count .. "/" .. total_count .. " movies loaded.")
 | 
			
		||||
    end
 | 
			
		||||
    return movies
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
local function search_movies(movies, search_term)
 | 
			
		||||
    local results = {}
 | 
			
		||||
    for movie_id, movie in pairs(movies) do
 | 
			
		||||
        if string.match(movie_id, search_term) or string.match(movie.name, search_term) or
 | 
			
		||||
            string.match(movie.description, search_term) then
 | 
			
		||||
                local item_string = ""
 | 
			
		||||
                if movie.item == true then
 | 
			
		||||
                    item_string = "yes"
 | 
			
		||||
                end
 | 
			
		||||
            table.insert(results, {movie_id, movie.name, item_string or ""})
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    if #results > 0 then
 | 
			
		||||
        return true, results
 | 
			
		||||
    else
 | 
			
		||||
        return false, results
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function get_movieformspec(movie_id, pagenum)
 | 
			
		||||
 | 
			
		||||
    local movie = yl_cinema.get_movie(movie_id)
 | 
			
		||||
    local screen_width = 12
 | 
			
		||||
    local screen_height = 6.75
 | 
			
		||||
    local screensize = screen_width .. "," .. 6.75
 | 
			
		||||
 | 
			
		||||
    local formspec = {}
 | 
			
		||||
    table.insert(formspec, "formspec_version[4]size[" .. screensize .. "]bgcolor[#000000]")
 | 
			
		||||
 | 
			
		||||
    if (not movie) or (not pagenum) then
 | 
			
		||||
        warn("Some error happened. movie=" .. dump(movie) .. ", page=" .. dump(pagenum))
 | 
			
		||||
        table.insert(formspec, "[0.5,0.5;Some Error happened.]")
 | 
			
		||||
        return table.concat(formspec, "")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if pagenum == 0 then
 | 
			
		||||
        table.insert(formspec, "background[0,0;" .. screensize .. ";" .. (F(movie.title_texture) or "") .. ";true]")
 | 
			
		||||
        table.insert(formspec, "label[0.5,0.5;" .. (F(movie.name) or "") .. "]")
 | 
			
		||||
        table.insert(formspec, "textarea[0.5,1.5;" .. screensize .. ";;" .. (F(movie.description) or "") .. ";]")
 | 
			
		||||
    else
 | 
			
		||||
        local page = movie.pages[pagenum]
 | 
			
		||||
 | 
			
		||||
        if not page then
 | 
			
		||||
            warn("Page empty = " .. dump(page))
 | 
			
		||||
            return ""
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        table.insert(formspec, "background[0,0;" .. screensize .. ";" .. (F(page.texture) or "") .. ";true]")
 | 
			
		||||
        table.insert(formspec, "label[" .. (F(page.captionposx) or 0) .. "," .. (F(page.captionposy) or 0) .. ";" ..
 | 
			
		||||
            (F(page.caption) or "") .. "]")
 | 
			
		||||
 | 
			
		||||
        if pagenum == #movie.pages then
 | 
			
		||||
            table.insert(formspec, "button[3," .. (F(screen_height) - 1) .. ";2,1;replay;Replay]")
 | 
			
		||||
            table.insert(formspec, "button_exit[6," .. (F(screen_height) - 1) .. ";2,1;exit;Exit]")
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return table.concat(formspec, "")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function showpage(target_player_name, movie_id, pagenum)
 | 
			
		||||
 | 
			
		||||
    if not minetest.get_player_by_name(target_player_name) then
 | 
			
		||||
        return
 | 
			
		||||
    end
 | 
			
		||||
    if watched_by(target_player_name) == "" then
 | 
			
		||||
        return
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local formspec = get_movieformspec(movie_id, pagenum)
 | 
			
		||||
 | 
			
		||||
    local movie = get_movie(movie_id)
 | 
			
		||||
    local pages = movie.pages
 | 
			
		||||
 | 
			
		||||
    if pagenum <= #pages then
 | 
			
		||||
 | 
			
		||||
        table.sort(pages, orderpages)
 | 
			
		||||
 | 
			
		||||
        local page = pages[pagenum] or {}
 | 
			
		||||
 | 
			
		||||
        local delay = page.duration or 3
 | 
			
		||||
        local nextpage = pagenum + 1
 | 
			
		||||
        minetest.after(delay, showpage, target_player_name, movie_id, nextpage)
 | 
			
		||||
        watches(target_player_name, movie_id)
 | 
			
		||||
        minetest.show_formspec(target_player_name, "yl_cinema:movie", formspec)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
    if formname ~= "yl_cinema:movie" then
 | 
			
		||||
        return
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local playername = player:get_player_name()
 | 
			
		||||
 | 
			
		||||
    if fields.exit or fields.quit then
 | 
			
		||||
        stops_watching(player)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if player and fields.replay then
 | 
			
		||||
        local movie_id = watched_by(playername)
 | 
			
		||||
        showpage(player:get_player_name(), movie_id, 0)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return true
 | 
			
		||||
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
minetest.register_on_leaveplayer(stops_watching)
 | 
			
		||||
minetest.register_on_dieplayer(stops_watching)
 | 
			
		||||
 | 
			
		||||
-- Chatcommands
 | 
			
		||||
 | 
			
		||||
function yl_cinema.cmd_list_movies(name, param)
 | 
			
		||||
 | 
			
		||||
    local args = string.split(param, " ")
 | 
			
		||||
 | 
			
		||||
    if (#args > 1) then
 | 
			
		||||
        return false, "Usage: /listmovies [<searchstring>]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local searchterm = args[1] or ""
 | 
			
		||||
 | 
			
		||||
    minetest.log("action", "[yl_cinema] Player " .. name .. " searches for movie " .. searchterm)
 | 
			
		||||
 | 
			
		||||
    local display_table = {{"movie_id","name","itemstring"}}
 | 
			
		||||
 | 
			
		||||
    local success, t = yl_cinema.listmovies(searchterm)
 | 
			
		||||
 | 
			
		||||
    for _,movies in ipairs(t) do
 | 
			
		||||
        table.insert(display_table, movies)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local nice_format = format_table(display_table)
 | 
			
		||||
 | 
			
		||||
    if success then
 | 
			
		||||
        return true, nice_format
 | 
			
		||||
    else
 | 
			
		||||
        return false, "No movies matching your criteria were found."
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.cmd_show_movie(name, param)
 | 
			
		||||
    local args = string.split(param, " ")
 | 
			
		||||
 | 
			
		||||
    if (#args ~= 2) then
 | 
			
		||||
        return false, "Usage: /showmovie <playername> <movie>"
 | 
			
		||||
    end
 | 
			
		||||
    if not minetest.get_player_by_name(args[1]) then
 | 
			
		||||
        return false, "Player not online"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local target_player_name = args[1] or ""
 | 
			
		||||
    local movie_id = args[2] or ""
 | 
			
		||||
 | 
			
		||||
    minetest.log("action", "[yl_cinema] Player " .. name .. " shows movie " .. movie_id .. " to " .. target_player_name)
 | 
			
		||||
 | 
			
		||||
    local success, msg = yl_cinema.startmovie(movie_id, target_player_name)
 | 
			
		||||
 | 
			
		||||
    if success then
 | 
			
		||||
        return true, msg
 | 
			
		||||
    else
 | 
			
		||||
        return false, msg
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.load_all_movies()
 | 
			
		||||
    yl_cinema.movies = yl_cinema.init_movies()
 | 
			
		||||
    for movie_id, _ in pairs(yl_cinema.movies) do
 | 
			
		||||
        local loaded_count, total_count = load_images_of_movie(movie_id)
 | 
			
		||||
        if loaded_count ~= total_count then
 | 
			
		||||
            yl_cinema.warn(loaded_count .. "/" .. total_count .. " images loaded for movie " .. movie_id)
 | 
			
		||||
        else
 | 
			
		||||
            yl_cinema.action(loaded_count .. "/" .. total_count .. " images loaded for movie " .. movie_id)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    return true, "Done."
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function movieid_to_item(movie_id)
 | 
			
		||||
    local itemstack = ItemStack(yl_cinema.movie_item_name_written)
 | 
			
		||||
    local meta = itemstack:get_meta()
 | 
			
		||||
    meta:set_string("_yl_cinema_movie_id", movie_id)
 | 
			
		||||
    meta:set_string("description", movie_id)
 | 
			
		||||
    return itemstack
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.imprint_movie(name, movie_id)
 | 
			
		||||
    -- Defense
 | 
			
		||||
    if not yl_cinema.movies or not yl_cinema.movies[movie_id] then
 | 
			
		||||
        return false, "Cannot find movie_id"
 | 
			
		||||
    end
 | 
			
		||||
    local pobj = minetest.get_player_by_name(name)
 | 
			
		||||
    if not pobj then
 | 
			
		||||
        return false, "Cannot find player"
 | 
			
		||||
    end
 | 
			
		||||
    local old_stack = pobj:get_wielded_item()
 | 
			
		||||
    if (not old_stack) or (old_stack:get_name() ~= yl_cinema.movie_item_name_empty) then
 | 
			
		||||
        return false, "Please wield an empty movie reel"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    -- Prepare new itemstack
 | 
			
		||||
    local new_stack = movieid_to_item(movie_id)
 | 
			
		||||
 | 
			
		||||
    -- Replace or add
 | 
			
		||||
    if old_stack:get_count() == 1 then
 | 
			
		||||
        -- replace
 | 
			
		||||
        pobj:set_wielded_item(new_stack)
 | 
			
		||||
        return true, ""
 | 
			
		||||
        
 | 
			
		||||
    else
 | 
			
		||||
        -- can we add?
 | 
			
		||||
        local inv = pobj:get_inventory()
 | 
			
		||||
        local listname = "main"
 | 
			
		||||
        
 | 
			
		||||
        if not inv:room_for_item(listname, new_stack) then
 | 
			
		||||
            return false, "No space in inventory for new print."
 | 
			
		||||
        end
 | 
			
		||||
        
 | 
			
		||||
        -- remove old
 | 
			
		||||
        old_stack:take_item(1)
 | 
			
		||||
        pobj:set_wielded_item(old_stack)
 | 
			
		||||
        -- add new
 | 
			
		||||
        inv:add_item(listname, new_stack)
 | 
			
		||||
        return true, ""
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.cmd_movie_reload(name, param)
 | 
			
		||||
    local args = string.split(param, " ")
 | 
			
		||||
 | 
			
		||||
    if (#args >= 2) then
 | 
			
		||||
        return false, "Usage: /movie_reload [<movie_id>]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local movie_id = args[1] or ""
 | 
			
		||||
 | 
			
		||||
    action("[yl_cinema] Player " .. name .. " reloads movie " .. movie_id)
 | 
			
		||||
 | 
			
		||||
    return yl_cinema.load_all_movies()
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.cmd_movie_imprint(name, param)
 | 
			
		||||
    local args = string.split(param, " ")
 | 
			
		||||
 | 
			
		||||
    if (#args > 1) then
 | 
			
		||||
        return false, "Usage: /movie_imprint [<movie_id>]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    local movie_id = args[1] or ""
 | 
			
		||||
 | 
			
		||||
    action("[yl_cinema] Player " .. name .. " imprints movie " .. movie_id)
 | 
			
		||||
 | 
			
		||||
    return yl_cinema.imprint_movie(name, movie_id)
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.listmovies(searchterm)
 | 
			
		||||
    return search_movies(yl_cinema.movies, searchterm)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.startmovie(movie_id, target_player_name)
 | 
			
		||||
    local pagenum = 0
 | 
			
		||||
    if not next(get_movie(movie_id)) then
 | 
			
		||||
        return false, "Movie " .. movie_id .. " not found."
 | 
			
		||||
    end
 | 
			
		||||
    watches(target_player_name, movie_id)
 | 
			
		||||
    -- Start to show a movie
 | 
			
		||||
    if minetest.get_player_by_name(target_player_name) then
 | 
			
		||||
        showpage(target_player_name, movie_id, pagenum)
 | 
			
		||||
        return true, "Movie " .. movie_id .. " started for " .. target_player_name
 | 
			
		||||
    else
 | 
			
		||||
        return false, "Player " .. target_player_name .. " not found."
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.load(filename, ...)
 | 
			
		||||
    return read_json_file(filename, ...)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.load_movies(movies_directory, ...)
 | 
			
		||||
    return load_movies(movies_directory, ...)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.search_movies(movies, search_term, ...)
 | 
			
		||||
    return search_movies(movies, search_term, ...)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.path_of_movie(movie_id, ...)
 | 
			
		||||
    return path_of_movie(movie_id, ...)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.load_images_of_movie(movie_id, ...)
 | 
			
		||||
    return load_images_of_movie(movie_id, ...)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.get_movie(movie_id, ...)
 | 
			
		||||
    return get_movie(movie_id, ...)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.string_to_recipe(recipestring, ...)
 | 
			
		||||
    return string_to_recipe(recipestring, ...)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function yl_cinema.orderpages(a, b, ...)
 | 
			
		||||
    return orderpages(a, b, ...)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
yl_cinema.action = action
 | 
			
		||||
yl_cinema.warn = warn
 | 
			
		||||
@ -1,4 +0,0 @@
 | 
			
		||||
 | 
			
		||||
local function get_files_in_directory(folderpath)
 | 
			
		||||
    return minetest.get_dir_list(folderpath, true)
 | 
			
		||||
end
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user