-------------------------------------------------------- -- Minetest :: Books Redux Mod (books_rx) -- -- See README.txt for licensing and other information. -- Copyright (c) 2019-2020, Leslie E. Krause -- -- ./games/minetest_game/mods/books_rx/init.lua -------------------------------------------------------- local config = minetest.load_config( ) local fs = minetest.formspec_escape local open_book_viewer, open_book_editor, open_paper_viewer, open_paper_editor ----------------------- function open_defbook_viewer( player_name, owner, title, text ) local function get_formspec( ) local formspec = "size[8.0,8.5]" .. default.gui_bg .. default.gui_bg_img .. "label[0.3,0.2;Title:]" .. "label[1.5,0.2;" .. title .. "]" .. "label[0.3,0.8;By:]" .. "label[1.5,0.8;" .. owner .. "]" .. "textarea[0.5,1.5;7.6,7.0;content;;" .. minetest.formspec_escape( text ) .. "]" .. "button_exit[3.0,7.8;2.0,0.8;close;Close]" return formspec end minetest.create_form( nil, player_name, get_formspec( ) ) end function open_book_viewer( player_name, oldtime, owner, title, scale, style, color, pages, marks, page_idx, vars, is_preview ) local book_scales = { small = { width = 12.0, height = 8.5 }, tall = { width = 12.0, height = 11.0 }, large = { width = 15.5, height = 11.0 }, wide = { width = 15.5, height = 8.5 }, } local book_colors = { gray = "#333333", brown = "#663300", teal = "#006633", purple = "#330066", olive = "#336600", indigo = "#003366", maroon = "#660033", red = "#660000", green = "#006600", blue = "#000066", } local mark_ver = 1 local function add_bookmark( ) if not table.get_index( marks, page_idx ) then table.insert( marks, page_idx ) table.sort( marks ) end end local function del_bookmark( ) local idx = table.get_index( marks, page_idx ) if idx then table.remove( marks, idx ) end end local function get_formspec( ) local page_width = book_scales[ scale ].width / 2 local page_height = book_scales[ scale ].height local foot_x1 = ( page_width - 4.5 ) / 2 + 0.3 -- horz pos of left-hand footer local foot_x2 = page_width + ( page_width - 4.5 ) / 2 - 0.3 -- horz pos of right-hand footer local foot_y = page_height - 1.3 -- vert pos of both footers if page_idx == 1 then -- render background and controls of front cover local formspec = string.format( "size[%0.2f,%0.2f]", page_width, page_height ) .. default.gui_bg .. string.format( "background[0.0,0.0;%0.2f,%0.2f;%s;false]", page_width, page_height, fs( "book_" .. style .. "_front.png^[colorize:" .. book_colors[ color ] .. "66^[noalpha" ) ) .. string.format( "%s[%0.2f,%0.2f;2.0,1.0;close;Close]", is_preview and "button" or "button_exit", foot_x1 + 0.8, foot_y ) .. string.format( "button[%0.2f,%0.2f;1.0,1.0;next_page;>>]", foot_x1 + 2.7, foot_y ) -- render front cover content local page_x1 = 0.8 local page_y1 = 0.5 local page_x2 = page_x1 + page_width - 1.4 local page_y2 = page_y1 + page_height - 1.5 formspec = formspec .. markup.get_formspec_string( markup.parse_message( pages[ page_idx ], vars ), page_x1, page_y1, page_x2, page_y2, "#666666", "#CCCCCC" ) return formspec else -- render background and controls of page local mark_idx = table.get_index( marks, page_idx ) local formspec = string.format( "size[%0.2f,%0.2f]", page_width * 2, page_height ) .. default.gui_bg .. string.format( "background[0.0,0.0;%0.2f,%0.2f;%s;false]", page_width, page_height, fs( "book_" .. style .. "_cover.png^[colorize:" .. book_colors[ color ] .. "66^[noalpha" ) ) .. string.format( "background[%0.2f,0.0;%0.2f,%0.2f;%s;false]", page_width, page_width, page_height, fs( "book_" .. style .. "_cover.png^[transformFX^[colorize:" .. book_colors[ color ] .. "66^[noalpha" ) ) .. string.format( "button[%0.2f,%0.2f;1.0,1.0;prev_page;<<]", foot_x2, foot_y ) .. string.format( "button[%0.2f,%0.2f;1.0,1.0;next_page;>>]", foot_x2 + 1.0, foot_y ) .. string.format( "%s[%0.2f,%0.2f;2.0,1.0;close;Close]", is_preview and "button" or "button_exit", foot_x2 + 2.5, foot_y ) .. string.format( "label[%0.2f,%0.2f;Bookmarks:]", foot_x1, foot_y + 0.2 ) if #marks > 0 then formspec = formspec .. string.format( "dropdown[%0.2f,%0.2f;1.8,1.0;marks_%d;,%s;%d;true]", foot_x1 + 1.5, foot_y + 0.1, mark_ver, table.join( marks, ",", function ( a, b ) return "Page " .. b - 1 end ), mark_idx and mark_idx + 1 or 1 ) else formspec = formspec .. string.format( "dropdown[%0.2f,%0.2f;1.8,1.0;marks;;1;true]", foot_x1 + 1.5, foot_y + 0.1 ) end if mark_idx then formspec = formspec .. string.format( "button[%0.2f,%0.2f;1.2,1.0;del_mark;Del]", foot_x1 + 3.3, foot_y ) else formspec = formspec .. string.format( "button[%0.2f,%0.2f;1.2,1.0;add_mark;Add]", foot_x1 + 3.3, foot_y ) end -- render left-hand page content local page_x1 = 1.0 local page_y1 = 0.5 local page_x2 = page_x1 + page_width - 1.4 local page_y2 = page_y1 + page_height - 1.8 local text_colors = { gray = "#999999", cyan = "#00EEEE", magenta = "#EE00EE", yellow = "#EEEE00", red = "#CC0000", green = "#00CC00", blue = "#0000CC", brown = "#CC9900", teal = "#00CC99", purple = "#9900CC", olive = "#99CC00", indigo = "#0099CC", maroon = "#CC0099", } formspec = formspec .. markup.get_formspec_string( markup.parse_message( pages[ page_idx ], vars, { colors = text_colors } ), page_x1, page_y1, page_x2, page_y2, "#666666", "#CCCCCC" ) if pages[ page_idx + 1 ] then -- render right-hand page content, if it exists page_x1 = page_x1 + page_width - 0.6 page_x2 = page_x2 + page_width - 0.6 formspec = formspec .. markup.get_formspec_string( markup.parse_message( pages[ page_idx + 1 ], vars ), page_x1, page_y1, page_x2, page_y2, "#666666", "#CCCCCC" ) end return formspec end end local function on_close( meta, player, fields ) local fields_marks = fields[ "marks_" .. mark_ver ] if fields.close then if is_preview then open_book_editor( player_name, oldtime, owner, title, scale, style, color, pages, page_idx, vars ) elseif mark_ver > 1 then local itemstack = player:get_wielded_item( ) local player_inv = player:get_inventory( ) local data = { oldtime = oldtime, owner = owner, title = title, scale = scale, style = style, color = color, pages = pages, marks = marks, } safety_deposit.encrypt_metadata( itemstack, data ) player:set_wielded_item( itemstack ) minetest.chat_send_player( player_name, "Your bookmarks were updated!" ) end elseif fields.next_page then if page_idx < #pages then page_idx = page_idx + 1 minetest.update_form( player_name, get_formspec( ) ) end elseif fields.prev_page then if page_idx > 1 then page_idx = page_idx - 1 minetest.update_form( player_name, get_formspec( ) ) end elseif fields.add_mark then mark_ver = mark_ver + 1 add_bookmark( page_idx ) minetest.update_form( player_name, get_formspec( ) ) elseif fields.del_mark then mark_ver = mark_ver + 1 del_bookmark( page_idx ) minetest.update_form( player_name, get_formspec( ) ) elseif fields_marks then -- overcome bug with dropdowns not updating values in older clients page_idx = marks[ fields_marks - 1 ] or 1 minetest.update_form( player_name, get_formspec( ) ) end end -- basic sanity check for proper inputs if not book_scales[ scale ] then scale = config.default_book_scale end if not book_colors[ color ] then color = config.default_book_color end if page_idx < 1 or page_idx > #pages then page_idx = 1 end minetest.create_form( nil, player_name, get_formspec( ), on_close, is_preview and minetest.FORMSPEC_SIGSTOP or nil ) end function open_book_editor( player_name, oldtime, owner, title, scale, style, color, pages, page_idx, vars ) local function sanitize( buf ) return string.trim( string.gsub( buf, ".", { ["\r"] = "\n", ["\t"] = " ", ["\f"] = "?", ["\b"] = "?" } ) ) .. "\n" end local function get_formspec( ) local book_scales = { "small", "large", "tall", "wide" } local book_colors = { "gray", "brown", "teal", "purple", "olive", "indigo", "maroon", "red", "green", "blue" } local book_styles = { "plain", "fancy", "classic", "vintage" } -- book texture filenames: -- books_cover_