From 38c80c4a5b30e9cb1128dad54e3073633c1a3d78 Mon Sep 17 00:00:00 2001 From: AliasAlreadyTaken Date: Fri, 2 Jun 2023 14:12:46 +0200 Subject: [PATCH] Bigscreen --- config.lua | 2 +- feature_bigscreen.lua | 4 +- feature_bigscreen_crafting.lua | 16 ++ feature_bigscreen_entity.lua | 204 +++++++++++++++++++++++++ feature_bigscreen_items.lua | 18 +-- internal.lua | 52 ++++--- textures/yl_cinema_block_bigscreen.png | Bin 0 -> 7749 bytes 7 files changed, 264 insertions(+), 32 deletions(-) create mode 100644 feature_bigscreen_crafting.lua create mode 100644 feature_bigscreen_entity.lua create mode 100644 textures/yl_cinema_block_bigscreen.png diff --git a/config.lua b/config.lua index ce55830..6a77732 100644 --- a/config.lua +++ b/config.lua @@ -14,4 +14,4 @@ yl_cinema.settings.enable_bigscreen = minetest.settings:get("yl_cinema.enable_bi yl_cinema.settings.enable_craft_bigscreen = minetest.settings:get("yl_cinema.enable_craft_bigscreen") or true yl_cinema.settings.enable_craft_bigscreen_recipe = minetest.settings:get("yl_cinema.enable_craft_bigscreen_recipe") or -"wool:grey,wool:grey,wool:grey,wool:grey,wool:grey,wool:grey,wool:black,,wool:black" +"wool:grey,wool:grey,wool:grey,wool:grey,wool:grey,wool:grey,wool:black, ,wool:black" diff --git a/feature_bigscreen.lua b/feature_bigscreen.lua index ba4e042..39c0004 100644 --- a/feature_bigscreen.lua +++ b/feature_bigscreen.lua @@ -1,3 +1,3 @@ dofile(yl_cinema.modpath .. "feature_bigscreen_items.lua") ---dofile(yl_cinema.modpath .. "feature_bigscreen_entity.lua") ---dofile(yl_cinema.modpath .. "feature_bigscreen_crafting.lua") \ No newline at end of file +dofile(yl_cinema.modpath .. "feature_bigscreen_entity.lua") +dofile(yl_cinema.modpath .. "feature_bigscreen_crafting.lua") \ No newline at end of file diff --git a/feature_bigscreen_crafting.lua b/feature_bigscreen_crafting.lua new file mode 100644 index 0000000..229c8b1 --- /dev/null +++ b/feature_bigscreen_crafting.lua @@ -0,0 +1,16 @@ +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 diff --git a/feature_bigscreen_entity.lua b/feature_bigscreen_entity.lua new file mode 100644 index 0000000..255d68a --- /dev/null +++ b/feature_bigscreen_entity.lua @@ -0,0 +1,204 @@ +if not (yl_cinema.settings.enable_bigscreen and yl_cinema.settings.enable_bigscreen == true) then + return +end + +local bigscreen_entity_name = "yl_cinema:movie_bigscreen" +local screen_width = 12 +local screen_height = 6.75 +local bigscreen_entity_initial_properties = {} +local bigscreen_entity_definition = { + initial_properties = bigscreen_entity_initial_properties, + visual = "sprite", + visual_size = { + x = screen_width, + y = screen_height + }, + glow = 15, + physical = false, + textures = {"yl_cinema_block_bigscreen.png^yl_cinema_icon_movie_inv.png"}, + _yl_cinema_stored_movie = "" +} + +minetest.register_entity(bigscreen_entity_name, bigscreen_entity_definition) + +-- Helper + +local function find_entity(pos) + local v = vector.new(0, 3.5, 0) + local center_pos = vector.add(pos, v) + for _, obj in pairs(minetest.get_objects_inside_radius(center_pos, 0.5)) do + if obj and obj:get_luaentity() and obj:get_luaentity().name == bigscreen_entity_name then + return obj + end + end +end + +-- Changepage + +local function showpage(ent_obj, 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, ent_obj, movie_id, nextpage) + + -- Payload + + if pagenum == 0 then + local properties = { + textures = {movie.title_texture}, + infotext = movie.name, + nametag = movie.decription + } + ent_obj:set_properties(properties) + else + if not page then + warn("Page empty = " .. dump(page)) + return "" + end + + local properties = { + textures = {page.texture}, + infotext = movie.name, + nametag = page.caption + } + + ent_obj:set_properties(properties) + + end + + end +end + +local function start_movie(ent_obj, movie_id) + if ent_obj and movie_id then + showpage(ent_obj, movie_id, 0) + else + return false, "Object " .. dump(ent_obj) .. " not found." + end +end + +-- Item + +local function get_formspec(pos) + local formspec = {} + table.insert(formspec, "formspec_version[4]size[10.75,7]") + table.insert(formspec, "list[context;movie;0.5,0.5;1,1;]") + table.insert(formspec, "list[current_player;main;0.5,2;8,4;]") + table.insert(formspec, "listring[]") + table.insert(formspec, "button_exit[9.7,0.3;0.75,0.75;quit;X]") + table.insert(formspec, "button[1.6,0.5;1.8,1;start0;Start]") + table.insert(formspec, "button[3.6,0.5;1.8,1;start3;3 Seconds]") + table.insert(formspec, "button[5.6,0.5;1.8,1;start5;5 Seconds]") + table.insert(formspec, "button[7.6,0.5;1.8,1;start10;10 Seconds]") + return table.concat(formspec, "") +end + +local function on_construct_node(pos) + local v = vector.new(0, 3.5, 0) + local center_pos = vector.add(pos, v) + + local meta = minetest.get_meta(pos) + local formspec = get_formspec(pos) + meta:set_string("formspec", formspec) + + local inv = meta:get_inventory() + inv:set_size("movie", 1) + + minetest.add_entity(center_pos, bigscreen_entity_name) +end + +local function on_destruct_node(pos) + local ent_obj = find_entity(pos) + ent_obj:remove() +end + +local function allow_metadata_inventory_put_node(pos, listname, index, stack, player) + local groupname = "movie" + local itemname = stack:get_name() + local playername = player:get_player_name() + if (not minetest.is_protected(pos, playername)) and (minetest.get_item_group(itemname, groupname) >= 1) then + return 1 + else + return 0 + end +end + +local function on_metadata_inventory_take_node(pos, listname, index, stack, player) + local playername = player:get_player_name() + if not minetest.is_protected(pos, playername) then + return 1 + else + return 0 + end +end + +local function can_dig_node(pos, player) + local playername = player:get_player_name() + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("movie") and not minetest.is_protected(pos, playername) +end + +local function on_receive_fields_node(pos, formname, fields, sender) + + if not next(fields) or fields.quit then + return + end + + local inv = minetest.get_meta(pos):get_inventory() + local itemstack = inv:get_stack("movie", 1) + local itemdef = itemstack:get_definition() + local movie_id = itemdef._yl_cinema_movie_id + local delay = 0 + + if fields.start0 then + delay = 0 + elseif fields.start3 then + delay = 3 + elseif fields.start5 then + delay = 5 + elseif fields.start10 then + delay = 10 + end + + -- Grab entity + + local ent_obj = find_entity(pos) + + core.after(delay, start_movie, ent_obj, movie_id) + +end + +local bigscreen_block_name = "yl_cinema:bigscreen_base" +local bigscreen_block_definition = { + description = "Cinema Base", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {{-0.5, -0.5, -0.5, 0.5, -0.4, 0.5}} + }, + groups = { + cracky = 3 + }, + tiles = {"yl_cinema_block_bigscreen.png^yl_cinema_icon_movie_inv.png", "yl_cinema_block_bigscreen.png", + "yl_cinema_block_bigscreen.png", "yl_cinema_block_bigscreen.png", "yl_cinema_block_bigscreen.png", + "yl_cinema_block_bigscreen.png"}, + can_dig = can_dig_node, + on_construct = on_construct_node, + on_destruct = on_destruct_node, + on_receive_fields = on_receive_fields_node, + on_metadata_inventory_take = on_metadata_inventory_take_node, + allow_metadata_inventory_put = allow_metadata_inventory_put_node, + allow_metadata_inventory_move = function() + return + end +} + +minetest.register_node(bigscreen_block_name, bigscreen_block_definition) diff --git a/feature_bigscreen_items.lua b/feature_bigscreen_items.lua index 6cee81b..2d1b48e 100644 --- a/feature_bigscreen_items.lua +++ b/feature_bigscreen_items.lua @@ -1,15 +1,14 @@ - -if not (yl_cinema.settings.enable_movieitems == true) then return end +if yl_cinema.settings.enable_movieitems ~= true then + return +end local function remove_forbidden_characters(str) local pattern = "[^%w_]" return string.gsub(str, pattern, "_") end -local name = "yl_cinema:movie" - -local movie_item_definition = -{ +local movie_item_name = "yl_cinema:movie" +local movie_item_definition = { groups = { movie = 1, not_in_creative_inventory = 1, @@ -19,15 +18,16 @@ local movie_item_definition = wield_image = "yl_cinema_icon_movie_inv.png", stack_max = 1, range = 4, - liquids_pointable = false, + liquids_pointable = false } for movie_id, movie in pairs(yl_cinema.movies) do if movie.item and (movie.item == true) then local item_definition = movie_item_definition item_definition._yl_cinema_movie_id = movie_id + core.log("action", "item_definition._yl_cinema_movie_id=" .. item_definition._yl_cinema_movie_id) item_definition.short_description = minetest.formspec_escape(movie.name) item_definition.description = minetest.formspec_escape(movie.description) - minetest.register_craftitem(name .. "_" .. remove_forbidden_characters(movie.name), item_definition) + minetest.register_craftitem(movie_item_name .. "_" .. remove_forbidden_characters(movie.name), item_definition) end -end \ No newline at end of file +end diff --git a/internal.lua b/internal.lua index ce904f4..b101215 100644 --- a/internal.lua +++ b/internal.lua @@ -120,7 +120,6 @@ end local function load_movies(movies_directory) local movies = {} local loaded_count = 0 - local total_count = 0 local movie_files = get_files_in_directory(movies_directory) for _, movie_id in ipairs(movie_files) do @@ -157,7 +156,7 @@ local function get_movieformspec(movie_id, pagenum) local screensize = screen_width .. "," .. 6.75 local formspec = {} - table.insert(formspec, "formspec_version[4]size[".. screensize.."]bgcolor[#000000]") + 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)) @@ -166,20 +165,24 @@ local function get_movieformspec(movie_id, pagenum) end if pagenum == 0 then - table.insert(formspec, "background[0,0;".. screensize..";" .. (F(movie.title_texture) or "") .. ";true]") + 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 "") .. ";]") + 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 + 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 "") .. "]") + 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]") + 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 @@ -189,8 +192,12 @@ 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 + 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) @@ -199,23 +206,25 @@ local function showpage(target_player_name, movie_id, pagenum) if pagenum <= #pages then - table.sort(pages,orderpages) + 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.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 + if formname ~= "yl_cinema:movie" then + return + end local playername = player:get_player_name() @@ -288,7 +297,9 @@ 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 + 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 @@ -303,13 +314,10 @@ 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 @@ -330,5 +338,9 @@ 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 diff --git a/textures/yl_cinema_block_bigscreen.png b/textures/yl_cinema_block_bigscreen.png new file mode 100644 index 0000000000000000000000000000000000000000..ea5a018e33c3b868e28c0603dade282ab2debaba GIT binary patch literal 7749 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 literal 0 HcmV?d00001