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
|
end
|
||||||
|
|
||||||
table.insert(fs, "container[0,5.6]")
|
table.insert(fs, "container[0,5.6]")
|
||||||
if data.recipes then
|
if data.recipes and #data.recipes > 0 then
|
||||||
recipe_fs(fs, data)
|
recipe_fs(fs, data)
|
||||||
elseif data.prev_item then
|
elseif data.prev_item then
|
||||||
table.insert(fs, ("label[2,1;%s]"):format(esc(data.show_usages
|
table.insert(fs, ("label[2,1;%s]"):format(esc(data.show_usages
|
||||||
|
@ -319,12 +319,12 @@ end
|
||||||
local function execute_search(data)
|
local function execute_search(data)
|
||||||
local filter = data.filter
|
local filter = data.filter
|
||||||
if filter == "" then
|
if filter == "" then
|
||||||
data.items = init_items
|
data.items = visible_items(data)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
data.items = {}
|
data.items = {}
|
||||||
|
|
||||||
for _, item in ipairs(init_items) do
|
for _, item in ipairs(visible_items(data)) do
|
||||||
local def = minetest.registered_items[item]
|
local def = minetest.registered_items[item]
|
||||||
local desc = def and minetest.get_translated_string(data.lang_code, def.description)
|
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.pagenum = 1
|
||||||
data.prev_item = nil
|
data.prev_item = nil
|
||||||
data.recipes = nil
|
data.recipes = nil
|
||||||
data.items = init_items
|
data.items = visible_items(data)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
elseif (fields.key_enter_field == "filter" or fields.search)
|
elseif (fields.key_enter_field == "filter" or fields.search)
|
||||||
|
@ -398,9 +398,9 @@ local function on_receive_fields(player, fields)
|
||||||
data.show_usages = nil
|
data.show_usages = nil
|
||||||
end
|
end
|
||||||
if data.show_usages then
|
if data.show_usages then
|
||||||
data.recipes = usages_cache[item]
|
data.recipes = known_recipes(data, usages_cache[item])
|
||||||
else
|
else
|
||||||
data.recipes = recipes_cache[item]
|
data.recipes = known_recipes(data, recipes_cache[item])
|
||||||
end
|
end
|
||||||
data.prev_item = item
|
data.prev_item = item
|
||||||
data.rnum = 1
|
data.rnum = 1
|
||||||
|
@ -415,7 +415,10 @@ minetest.register_on_joinplayer(function(player)
|
||||||
player_data[name] = {
|
player_data[name] = {
|
||||||
filter = "",
|
filter = "",
|
||||||
pagenum = 1,
|
pagenum = 1,
|
||||||
items = init_items,
|
items = {},
|
||||||
|
held_items = {},
|
||||||
|
held_groups = {},
|
||||||
|
known_items = {},
|
||||||
lang_code = info.lang_code
|
lang_code = info.lang_code
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
@ -436,3 +439,124 @@ sfinv.register_page("mtg_craftguide:craftguide", {
|
||||||
end
|
end
|
||||||
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