2019-08-20 18:54:48 +00:00
|
|
|
|
2019-11-08 18:39:07 +00:00
|
|
|
local page_cache = {}
|
2019-11-20 11:55:10 +00:00
|
|
|
local recipe_cache = {}
|
|
|
|
local group_cache = {}
|
|
|
|
|
|
|
|
local function resolve_group(group)
|
|
|
|
if group_cache[group] then return group_cache[group] end
|
|
|
|
local remove_group = group:sub(7)
|
|
|
|
local found
|
|
|
|
for v in pairs(minetest.registered_items) do
|
|
|
|
if minetest.get_item_group(v, remove_group) > 0 then
|
|
|
|
found = v
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if not found then return "" end
|
|
|
|
group_cache[group] = found
|
|
|
|
return found
|
|
|
|
end
|
|
|
|
|
|
|
|
local function fromtable_output(tbl, out)
|
|
|
|
local res
|
|
|
|
for _,v in pairs(tbl) do
|
|
|
|
if v.output == out then
|
|
|
|
res = v
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return res
|
|
|
|
end
|
|
|
|
|
|
|
|
local function generate_recipe_hypertext(item, recipe_type)
|
|
|
|
if recipe_cache[recipe_type .. "/" .. item] then return recipe_cache[recipe_type .. "/" .. item] end
|
|
|
|
|
|
|
|
local lines = {}
|
|
|
|
|
|
|
|
if recipe_type == 'cauldron' then
|
|
|
|
local x = fromtable_output(magicalities.cauldron.recipes, item)
|
|
|
|
if not x then return "" end
|
|
|
|
local rec = x.requirements
|
|
|
|
local y = {}
|
|
|
|
|
|
|
|
for _,v in pairs(x.items) do
|
|
|
|
table.insert(y, "<item name=\""..v.."\" width=64 height=64>")
|
|
|
|
end
|
|
|
|
|
|
|
|
table.insert(lines, "<center>" .. table.concat(y, "<img name=magicalities_book_plus.png width=64 height=64>") .. "</center>")
|
|
|
|
table.insert(lines, "<center><img name=gui_furnace_arrow_bg.png^\\[transformFY width=64 height=64></center>")
|
|
|
|
table.insert(lines, "<center><item name=\"magicalities:cauldron_with_water\" width=64 height=64><img name=magicalities_book_plus.png width=64 height=64><item name=\"magicalities:wand_steel\" width=64 height=64></center>")
|
|
|
|
|
|
|
|
if rec then
|
|
|
|
local p = {}
|
|
|
|
for rec,v in pairs(rec) do
|
|
|
|
table.insert(p, v .. " " .. magicalities.elements[rec].description)
|
|
|
|
end
|
|
|
|
table.insert(lines, "<center><big>" .. table.concat(p, " | ") .. "</big></center>")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if #lines > 0 then
|
|
|
|
local ht = table.concat(lines, "\n")
|
|
|
|
recipe_cache[recipe_type .. "/" .. item] = ht
|
|
|
|
return ht
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function line_special (line)
|
|
|
|
local types = {"cauldron"}
|
|
|
|
local matched = false
|
|
|
|
|
|
|
|
for _,v in pairs(types) do
|
|
|
|
matched = line:match("^<"..v) ~= nil
|
|
|
|
if matched then break end
|
|
|
|
end
|
|
|
|
|
|
|
|
if not matched then return line end
|
|
|
|
local tyt = line:match("^<([%w]*)")
|
|
|
|
local itm = line:match("name=([^>]*)")
|
|
|
|
if not tyt or not itm then return "" end
|
|
|
|
return generate_recipe_hypertext(itm, tyt)
|
|
|
|
end
|
2019-11-08 18:39:07 +00:00
|
|
|
|
|
|
|
local function book_formspec(user, page, scrollindex)
|
|
|
|
if page then
|
|
|
|
return "size[8,8]"..
|
|
|
|
"button[0,0;2,1;back;Back to index]"..
|
|
|
|
"hypertext[0.1,0.5;7.9,7.5;text;"..page_cache[page].."]"..
|
|
|
|
default.gui_bg..
|
|
|
|
default.gui_bg_img..
|
|
|
|
default.gui_slots
|
|
|
|
end
|
|
|
|
|
2019-11-07 19:10:15 +00:00
|
|
|
local avail_list = magicalities.available_to_player(user, true)
|
2019-11-08 18:39:07 +00:00
|
|
|
return "size[6,5.7]"..
|
2019-11-07 19:10:15 +00:00
|
|
|
default.gui_bg..
|
|
|
|
default.gui_bg_img..
|
2019-11-08 18:39:07 +00:00
|
|
|
default.gui_slots..
|
|
|
|
magicalities.researching.generate_formspec_list(avail_list, 0, 0, 5, 5.25, scrollindex, false, true)
|
|
|
|
end
|
|
|
|
|
|
|
|
local function first_key(list)
|
|
|
|
local ekey
|
|
|
|
for key,_ in pairs(list) do
|
|
|
|
ekey = key
|
|
|
|
break
|
|
|
|
end
|
|
|
|
return ekey
|
|
|
|
end
|
|
|
|
|
|
|
|
local function book_read_page(book, user, page, ptype)
|
|
|
|
local uname = user:get_player_name()
|
|
|
|
local check = magicalities.player_has_ability
|
|
|
|
if ptype == 2 then
|
|
|
|
check = magicalities.player_has_recipe
|
|
|
|
end
|
|
|
|
|
2019-11-09 12:32:59 +00:00
|
|
|
if not check(uname, page) then return false end
|
2019-11-08 18:39:07 +00:00
|
|
|
|
|
|
|
local chapter = "#"..ptype..""..page
|
|
|
|
if not page_cache[chapter] then
|
2019-11-09 12:32:59 +00:00
|
|
|
return false
|
2019-11-08 18:39:07 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
minetest.show_formspec(uname, "magicalities:book", book_formspec(uname, chapter, 0))
|
2019-11-09 12:32:59 +00:00
|
|
|
return true
|
2019-11-07 19:10:15 +00:00
|
|
|
end
|
|
|
|
|
2019-11-08 18:39:07 +00:00
|
|
|
local function book_read(book, user, pointed_thing)
|
2019-11-07 19:10:15 +00:00
|
|
|
local uname = user:get_player_name()
|
2019-11-09 12:32:59 +00:00
|
|
|
if pointed_thing and pointed_thing.type == "node" then
|
|
|
|
local pos = pointed_thing.under
|
|
|
|
local node = minetest.get_node(pos)
|
|
|
|
local ptype = 2
|
|
|
|
local page = node.name
|
|
|
|
|
|
|
|
-- Special case for crystals
|
|
|
|
if minetest.get_item_group(node.name, "crystal_cluster") > 0 then
|
|
|
|
ptype = 1
|
|
|
|
page = "magicalities:crystal"
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Open a page instead
|
|
|
|
if page_cache["#"..ptype..""..page] then
|
|
|
|
local read = book_read_page(book, user, page, ptype)
|
|
|
|
if read then
|
|
|
|
return book
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-11-08 18:39:07 +00:00
|
|
|
local meta = book:get_meta()
|
|
|
|
minetest.show_formspec(uname, "magicalities:book", book_formspec(uname, nil, meta:get_int("scrolli")))
|
|
|
|
return book
|
|
|
|
end
|
|
|
|
|
|
|
|
local function cache_book_pages()
|
2019-11-20 11:55:10 +00:00
|
|
|
recipe_cache = {}
|
2019-11-08 18:39:07 +00:00
|
|
|
local file = io.open(minetest.get_modpath("magicalities").."/book.txt")
|
|
|
|
local all = {}
|
|
|
|
local previous = ""
|
|
|
|
local since = 0
|
|
|
|
|
|
|
|
for line in file:lines() do
|
|
|
|
if line:sub(0,1) == "#" then
|
|
|
|
all[line] = ""
|
|
|
|
previous = line
|
|
|
|
since = 0
|
|
|
|
elseif previous ~= "" then
|
2019-11-20 11:55:10 +00:00
|
|
|
line = line_special(line)
|
2019-11-08 18:39:07 +00:00
|
|
|
if since > 0 then
|
|
|
|
line = '\n'..line
|
|
|
|
end
|
|
|
|
all[previous] = all[previous] .. line
|
|
|
|
since = since + 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
page_cache = all
|
2019-11-07 19:10:15 +00:00
|
|
|
end
|
|
|
|
|
2019-11-08 18:39:07 +00:00
|
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
|
|
if formname ~= "magicalities:book" then return false end
|
|
|
|
|
|
|
|
local book = player:get_wielded_item()
|
|
|
|
if book:get_name() ~= "magicalities:book" then return true end
|
|
|
|
|
|
|
|
local bmeta = book:get_meta()
|
|
|
|
|
|
|
|
local scrolled = false
|
|
|
|
local findex = bmeta:get_int("scrolli")
|
|
|
|
|
|
|
|
local page
|
|
|
|
local page_type
|
|
|
|
|
|
|
|
local fkey = first_key(fields)
|
|
|
|
if fields["text"] and fields["text"]:sub(0,6) == "action" then
|
|
|
|
local pact = fields["text"]:sub(8):gsub("\"", "")
|
|
|
|
if pact then
|
|
|
|
fkey = pact
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if fields["dn"] then
|
|
|
|
scrolled = true
|
|
|
|
findex = findex + 1
|
|
|
|
elseif fields["up"] then
|
|
|
|
scrolled = true
|
|
|
|
findex = findex - 1
|
|
|
|
if findex < 0 then
|
|
|
|
findex = 0
|
|
|
|
end
|
|
|
|
elseif fkey and fkey:sub(0,1) == "#" then
|
|
|
|
page_type = tonumber(fkey:sub(2,2))
|
|
|
|
page = fkey:sub(3)
|
|
|
|
elseif fields["back"] then
|
|
|
|
book_read(book, player)
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
if scrolled then
|
|
|
|
bmeta:set_int("scrolli", findex)
|
|
|
|
player:set_wielded_item(book)
|
|
|
|
book_read(book, player)
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
if not page or not page_type then return true end
|
|
|
|
-- Handle page
|
|
|
|
--print("Open page on topic " .. page .. ", which is of type " .. page_type)
|
|
|
|
book_read_page(book, player, page, page_type)
|
|
|
|
|
|
|
|
return true
|
|
|
|
end)
|
|
|
|
|
2019-11-23 19:18:05 +00:00
|
|
|
local mgww = "Magicalities' Guide for Witches and Wizards"
|
2019-08-20 18:54:48 +00:00
|
|
|
minetest.register_craftitem("magicalities:book", {
|
2019-11-23 19:18:05 +00:00
|
|
|
description = mgww,
|
2019-08-20 18:54:48 +00:00
|
|
|
inventory_image = "magicalities_book.png",
|
2019-11-09 12:32:59 +00:00
|
|
|
on_use = book_read,
|
2019-11-07 19:10:15 +00:00
|
|
|
on_place = book_read,
|
|
|
|
on_secondary_use = book_read,
|
|
|
|
_wand_created = function (itemstack, wand, user, pos)
|
2019-11-23 19:18:05 +00:00
|
|
|
local meta = itemstack:get_meta()
|
|
|
|
local name = user:get_player_name()
|
|
|
|
meta:set_string("player", name)
|
|
|
|
meta:set_string("description", mgww .. "\n" ..
|
|
|
|
minetest.colorize("#d33b57", string.format("Soulbound to %s", name)))
|
2019-08-20 18:54:48 +00:00
|
|
|
return itemstack
|
2019-11-08 12:48:12 +00:00
|
|
|
end,
|
|
|
|
stack_max = 1
|
2019-11-07 19:10:15 +00:00
|
|
|
})
|
2019-11-08 18:39:07 +00:00
|
|
|
|
|
|
|
minetest.register_chatcommand("mgcbookcache", {
|
|
|
|
privs = {basic_privs = 1},
|
|
|
|
func = function ()
|
|
|
|
cache_book_pages()
|
|
|
|
return true, "Reloaded book cache successfully."
|
|
|
|
end
|
|
|
|
})
|
|
|
|
|
2019-11-20 11:55:10 +00:00
|
|
|
local initial = true
|
|
|
|
minetest.register_on_joinplayer(function ()
|
|
|
|
if not initial then return end
|
|
|
|
initial = false
|
|
|
|
cache_book_pages()
|
|
|
|
end)
|