Add basic support for progressive mode
What’s lacking: Saving held items, a game setting.
This commit is contained in:
parent
dddc857e15
commit
e4d566b13a
138
init.lua
138
init.lua
|
@ -300,7 +300,7 @@ local function get_formspec(player)
|
|||
end
|
||||
|
||||
table.insert(fs, "container[0,5.6]")
|
||||
if data.recipes then
|
||||
if data.recipes and #data.recipes > 0 then
|
||||
recipe_fs(fs, data)
|
||||
elseif data.prev_item then
|
||||
table.insert(fs, ("label[2,1;%s]"):format(esc(data.show_usages
|
||||
|
@ -319,12 +319,12 @@ end
|
|||
local function execute_search(data)
|
||||
local filter = data.filter
|
||||
if filter == "" then
|
||||
data.items = init_items
|
||||
data.items = visible_items(data)
|
||||
return
|
||||
end
|
||||
data.items = {}
|
||||
|
||||
for _, item in ipairs(init_items) do
|
||||
for _, item in ipairs(visible_items(data)) do
|
||||
local def = minetest.registered_items[item]
|
||||
local desc = def and minetest.get_translated_string(data.lang_code, def.description)
|
||||
|
||||
|
@ -343,7 +343,7 @@ local function on_receive_fields(player, fields)
|
|||
data.pagenum = 1
|
||||
data.prev_item = nil
|
||||
data.recipes = nil
|
||||
data.items = init_items
|
||||
data.items = visible_items(data)
|
||||
return true
|
||||
|
||||
elseif (fields.key_enter_field == "filter" or fields.search)
|
||||
|
@ -398,9 +398,9 @@ local function on_receive_fields(player, fields)
|
|||
data.show_usages = nil
|
||||
end
|
||||
if data.show_usages then
|
||||
data.recipes = usages_cache[item]
|
||||
data.recipes = known_recipes(data, usages_cache[item])
|
||||
else
|
||||
data.recipes = recipes_cache[item]
|
||||
data.recipes = known_recipes(data, recipes_cache[item])
|
||||
end
|
||||
data.prev_item = item
|
||||
data.rnum = 1
|
||||
|
@ -415,7 +415,10 @@ minetest.register_on_joinplayer(function(player)
|
|||
player_data[name] = {
|
||||
filter = "",
|
||||
pagenum = 1,
|
||||
items = init_items,
|
||||
items = {},
|
||||
held_items = {},
|
||||
held_groups = {},
|
||||
known_items = {},
|
||||
lang_code = info.lang_code
|
||||
}
|
||||
end)
|
||||
|
@ -436,3 +439,124 @@ sfinv.register_page("mtg_craftguide:craftguide", {
|
|||
end
|
||||
end
|
||||
})
|
||||
|
||||
-- ~ Progressive-mode support ~
|
||||
-- [The vast majority of changes to mtg_craftguide are found here!]
|
||||
function table_to_str(table)
|
||||
local ret = "["
|
||||
for k,v in pairs(table) do
|
||||
ret = ret .. "; " .. k .. " - "
|
||||
if type(v) == "table" then
|
||||
ret = ret .. table_to_str(v)
|
||||
else
|
||||
ret = ret .. v
|
||||
end
|
||||
end
|
||||
return ret .. "]"
|
||||
end
|
||||
|
||||
-- Given a player’s data and a recipe, return whether or not that recipe
|
||||
-- is “known” by the player. (That is, they have held all necessary inputs.)
|
||||
function known_recipe(data, recipe)
|
||||
for _,input in pairs(recipe.items) do
|
||||
if (not data.held_items[input:gsub(" .*", "")]) and (not data.held_groups[input]) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- From a table of recipes, return a sub-table of recipes that are “known.”
|
||||
function known_recipes(data, recipes)
|
||||
local ret = {}
|
||||
if recipes then
|
||||
for _,recipe in pairs(recipes) do
|
||||
if known_recipe(data, recipe) then
|
||||
table.insert(ret, recipe)
|
||||
end
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
-- Given a player’s data and an item-name, return a table of all items the
|
||||
-- player should “know of” that can be crafted from that item.
|
||||
function known_crafting_outputs(data, item_name)
|
||||
local outputs = {}
|
||||
local uses = usages_cache[item_name]
|
||||
if uses then
|
||||
for _,recipe in pairs(uses) do
|
||||
if known_recipe(data, recipe) then
|
||||
local out_name = recipe.output
|
||||
out_name = out_name:gsub(" .*", "")
|
||||
table.insert(outputs, out_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
return outputs
|
||||
end
|
||||
|
||||
-- Returns a table of all items that are “known” to the player; either they’ve
|
||||
-- been held by them, or they’re craftable using solely objects held previously.
|
||||
function visible_items(data)
|
||||
local ret = {}
|
||||
for item,_ in pairs(data.held_items) do
|
||||
table.insert(ret, item)
|
||||
end
|
||||
for item,_ in pairs(data.known_items) do
|
||||
table.insert(ret, item)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
-- To be executed whenever a player gains/picks up an item.
|
||||
-- If the item is new, it is added to the player’s held_items table, and then
|
||||
-- possible outputs from it (and other known items) are added to known_items.
|
||||
function update_known_items(player, item_name)
|
||||
local name = player:get_player_name()
|
||||
local data = player_data[name]
|
||||
|
||||
if not data.held_items[item_name] then
|
||||
-- Mark the new item as known.
|
||||
data.held_items[item_name] = true
|
||||
|
||||
-- Mark the new item’s groups as known.
|
||||
local groups = minetest.registered_items[item_name].groups
|
||||
for group,rating in pairs(groups) do
|
||||
if rating > 0 then
|
||||
data.held_groups["group:" .. group] = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Mark items craftable with this (and other) items as known.
|
||||
for _,out_item_name in pairs(known_crafting_outputs(data, item_name)) do
|
||||
data.known_items[out_item_name] = true
|
||||
end
|
||||
|
||||
-- Reset item-list.
|
||||
data.items = visible_items(data)
|
||||
|
||||
-- Notify the player.
|
||||
minetest.chat_send_player(name, S("New recipes unlocked!"))
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_item_pickup(function(itemstack, picker)
|
||||
update_known_items(picker, itemstack:get_name())
|
||||
end)
|
||||
|
||||
minetest.register_on_player_inventory_action(function(player, action, inv, inv_info)
|
||||
if action == "put" then
|
||||
update_known_items(player, inv_info.stack:get_name())
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_dignode(function(pos, oldnode, digger)
|
||||
update_known_items(digger, oldnode.name)
|
||||
end)
|
||||
|
||||
minetest.register_on_craft(function(itemstack, player)
|
||||
update_known_items(player, itemstack:get_name())
|
||||
end)
|
||||
|
||||
|
||||
|
|
Ŝarĝante…
Reference in New Issue