From fc53035ec7a41f09f4995544c4371a4acbc283c5 Mon Sep 17 00:00:00 2001 From: random-geek <35757396+random-geek@users.noreply.github.com> Date: Sat, 3 Oct 2020 14:56:06 -0700 Subject: [PATCH] Convert indentation --- api.lua | 384 ++++++++++++++++++------------------- autocrafting.lua | 278 +++++++++++++-------------- init.lua | 144 +++++++------- inventory.lua | 482 +++++++++++++++++++++++------------------------ 4 files changed, 644 insertions(+), 644 deletions(-) diff --git a/api.lua b/api.lua index b436f6a..98d8b73 100644 --- a/api.lua +++ b/api.lua @@ -1,216 +1,216 @@ -- TODO: aliases? local get_drops = function(item, def) - local normalDrops = {} - local randomDrops = {} - - if type(def.drop) == "table" then - -- Handle complex drops. This is the method used by Unified Inventory. - local maxStart = true - local itemsLeft = def.drop.max_items - local dropTables = def.drop.items or {} - - local dStack, dName, dCount - - for _, dropTable in ipairs(dropTables) do - if itemsLeft and itemsLeft <= 0 then break end - - for _, dropItem in ipairs(dropTable.items) do - dStack = ItemStack(dropItem) - dName = dStack:get_name() - dCount = dStack:get_count() - - if dCount > 0 and dName ~= item then - if #dropTable.items == 1 and dropTable.rarity == 1 and maxStart then - normalDrops[dName] = (normalDrops[dName] or 0) + dCount - - if itemsLeft then - itemsLeft = itemsLeft - 1 - if itemsLeft <= 0 then break end - end - else - if itemsLeft then maxStart = false end - - randomDrops[dName] = (randomDrops[dName] or 0) + dCount - end - end - end - end - else - -- Handle simple, one-item drops. - local dStack = ItemStack(def.drop) - - if not dStack:is_empty() and dStack:get_name() ~= item then - normalDrops[dStack:get_name()] = dStack:get_count() - end - end - - return normalDrops, randomDrops + local normalDrops = {} + local randomDrops = {} + + if type(def.drop) == "table" then + -- Handle complex drops. This is the method used by Unified Inventory. + local maxStart = true + local itemsLeft = def.drop.max_items + local dropTables = def.drop.items or {} + + local dStack, dName, dCount + + for _, dropTable in ipairs(dropTables) do + if itemsLeft and itemsLeft <= 0 then break end + + for _, dropItem in ipairs(dropTable.items) do + dStack = ItemStack(dropItem) + dName = dStack:get_name() + dCount = dStack:get_count() + + if dCount > 0 and dName ~= item then + if #dropTable.items == 1 and dropTable.rarity == 1 and maxStart then + normalDrops[dName] = (normalDrops[dName] or 0) + dCount + + if itemsLeft then + itemsLeft = itemsLeft - 1 + if itemsLeft <= 0 then break end + end + else + if itemsLeft then maxStart = false end + + randomDrops[dName] = (randomDrops[dName] or 0) + dCount + end + end + end + end + else + -- Handle simple, one-item drops. + local dStack = ItemStack(def.drop) + + if not dStack:is_empty() and dStack:get_name() ~= item then + normalDrops[dStack:get_name()] = dStack:get_count() + end + end + + return normalDrops, randomDrops end cg.build_item_list = function() - local startTime = minetest.get_us_time() - cg.items_all.list = {} - - for item, def in pairs(minetest.registered_items) do - if def.description and def.description ~= "" and - minetest.get_item_group(item, "not_in_creative_inventory") == 0 and - minetest.get_item_group(item, "not_in_craft_guide") == 0 then - table.insert(cg.items_all.list, item) - cg.crafts[item] = minetest.get_all_craft_recipes(item) or {} - end - end - - local def, fuel, decremented - - for _, item in ipairs(cg.items_all.list) do - def = minetest.registered_items[item] - - fuel, decremented = minetest.get_craft_result({method = "fuel", width = 0, items = {ItemStack(item)}}) - - if fuel.time > 0 then - table.insert(cg.crafts[item], { - type = "fuel", - items = {item}, - output = decremented.items[1]:to_string(), - time = fuel.time, - }) - end - - if def.drop then - local normalDrops, randomDrops = get_drops(item, def) - - for dItem, dCount in pairs(normalDrops) do - if cg.crafts[dItem] then - table.insert(cg.crafts[dItem], { - type = "digging", - width = 0, - items = {item}, - output = ItemStack({name = dItem, count = dCount}):to_string() - }) - end - end - - for dItem, dCount in pairs(randomDrops) do - if cg.crafts[dItem] then - table.insert(cg.crafts[dItem], { - type = "digging_chance", - width = 0, - items = {item}, - output = ItemStack({name = dItem, count = dCount}):to_string() - }) - end - end - end - - for group, _ in pairs(def.groups) do - if not cg.group_stereotypes[group] then - cg.group_stereotypes[group] = item - end - end - end - - table.sort(cg.items_all.list) - cg.items_all.num_pages = math.ceil(#cg.items_all.list / cg.PAGE_ITEMS) - - minetest.log("info", string.format("[cg_plus] Finished building item list in %.3f s.", - (minetest.get_us_time() - startTime) / 1000000)) + local startTime = minetest.get_us_time() + cg.items_all.list = {} + + for item, def in pairs(minetest.registered_items) do + if def.description and def.description ~= "" and + minetest.get_item_group(item, "not_in_creative_inventory") == 0 and + minetest.get_item_group(item, "not_in_craft_guide") == 0 then + table.insert(cg.items_all.list, item) + cg.crafts[item] = minetest.get_all_craft_recipes(item) or {} + end + end + + local def, fuel, decremented + + for _, item in ipairs(cg.items_all.list) do + def = minetest.registered_items[item] + + fuel, decremented = minetest.get_craft_result({method = "fuel", width = 0, items = {ItemStack(item)}}) + + if fuel.time > 0 then + table.insert(cg.crafts[item], { + type = "fuel", + items = {item}, + output = decremented.items[1]:to_string(), + time = fuel.time, + }) + end + + if def.drop then + local normalDrops, randomDrops = get_drops(item, def) + + for dItem, dCount in pairs(normalDrops) do + if cg.crafts[dItem] then + table.insert(cg.crafts[dItem], { + type = "digging", + width = 0, + items = {item}, + output = ItemStack({name = dItem, count = dCount}):to_string() + }) + end + end + + for dItem, dCount in pairs(randomDrops) do + if cg.crafts[dItem] then + table.insert(cg.crafts[dItem], { + type = "digging_chance", + width = 0, + items = {item}, + output = ItemStack({name = dItem, count = dCount}):to_string() + }) + end + end + end + + for group, _ in pairs(def.groups) do + if not cg.group_stereotypes[group] then + cg.group_stereotypes[group] = item + end + end + end + + table.sort(cg.items_all.list) + cg.items_all.num_pages = math.ceil(#cg.items_all.list / cg.PAGE_ITEMS) + + minetest.log("info", string.format("[cg_plus] Finished building item list in %.3f s.", + (minetest.get_us_time() - startTime) / 1000000)) end cg.filter_items = function(player, filter) - local playerName = player:get_player_name() - - if not filter or filter == "" then - cg.items_filtered[playerName] = nil - return - end - - cg.items_filtered[playerName] = {list = {}} - - local groupFilter = string.sub(filter, 1, 6) == "group:" and filter:sub(7) - - if groupFilter and cg.group_search then - -- Search by group - local groups = string.split(groupFilter, ",") - local isInGroups - - for _, item in ipairs(cg.items_all.list) do - isInGroups = true - - for idx = 1, math.min(#groups, cg.group_search_max) do - if minetest.get_item_group(item, groups[idx]) == 0 then - isInGroups = false - break - end - end - - if isInGroups then - table.insert(cg.items_filtered[playerName].list, item) - end - end - else - -- Regular search - for _, item in ipairs(cg.items_all.list) do - if item:lower():find(filter, 1, true) or - minetest.registered_items[item].description:lower():find(filter, 1, true) then - table.insert(cg.items_filtered[playerName].list, item) - end - end - end - - cg.items_filtered[playerName].num_pages = math.ceil(#cg.get_item_list(player).list / cg.PAGE_ITEMS) + local playerName = player:get_player_name() + + if not filter or filter == "" then + cg.items_filtered[playerName] = nil + return + end + + cg.items_filtered[playerName] = {list = {}} + + local groupFilter = string.sub(filter, 1, 6) == "group:" and filter:sub(7) + + if groupFilter and cg.group_search then + -- Search by group + local groups = string.split(groupFilter, ",") + local isInGroups + + for _, item in ipairs(cg.items_all.list) do + isInGroups = true + + for idx = 1, math.min(#groups, cg.group_search_max) do + if minetest.get_item_group(item, groups[idx]) == 0 then + isInGroups = false + break + end + end + + if isInGroups then + table.insert(cg.items_filtered[playerName].list, item) + end + end + else + -- Regular search + for _, item in ipairs(cg.items_all.list) do + if item:lower():find(filter, 1, true) or + minetest.registered_items[item].description:lower():find(filter, 1, true) then + table.insert(cg.items_filtered[playerName].list, item) + end + end + end + + cg.items_filtered[playerName].num_pages = math.ceil(#cg.get_item_list(player).list / cg.PAGE_ITEMS) end cg.parse_craft = function(craft) - local type = craft.type - local template = cg.craft_types[type] or {} - - if craft.width == 0 and template.alt_zero_width then - type = template.alt_zero_width - template = cg.craft_types[template.alt_zero_width] or {} - end - - local newCraft = { - type = type, - items = {}, - output = craft.output, - } - - if template.get_infotext then - newCraft.infotext = template.get_infotext(craft) or "" - end - - local width = math.max(craft.width or 0, 1) - - if template.get_grid_size then - newCraft.grid_size = template.get_grid_size(craft) - else - newCraft.grid_size = {x = width, y = math.ceil(table.maxn(craft.items) / width)} - end - - if template.inherit_width then - -- For shapeless recipes, there is no need to modify the item list. - newCraft.items = craft.items - else - -- The craft's width is not always the same as the grid size, so items need to be shifted around. - for idx, item in pairs(craft.items) do - newCraft.items[idx + (newCraft.grid_size.x - width) * math.floor((idx - 1) / width)] = item - end - end - - return newCraft + local type = craft.type + local template = cg.craft_types[type] or {} + + if craft.width == 0 and template.alt_zero_width then + type = template.alt_zero_width + template = cg.craft_types[template.alt_zero_width] or {} + end + + local newCraft = { + type = type, + items = {}, + output = craft.output, + } + + if template.get_infotext then + newCraft.infotext = template.get_infotext(craft) or "" + end + + local width = math.max(craft.width or 0, 1) + + if template.get_grid_size then + newCraft.grid_size = template.get_grid_size(craft) + else + newCraft.grid_size = {x = width, y = math.ceil(table.maxn(craft.items) / width)} + end + + if template.inherit_width then + -- For shapeless recipes, there is no need to modify the item list. + newCraft.items = craft.items + else + -- The craft's width is not always the same as the grid size, so items need to be shifted around. + for idx, item in pairs(craft.items) do + newCraft.items[idx + (newCraft.grid_size.x - width) * math.floor((idx - 1) / width)] = item + end + end + + return newCraft end cg.get_item_list = function(player) - return cg.items_filtered[player:get_player_name()] or cg.items_all + return cg.items_filtered[player:get_player_name()] or cg.items_all end cg.register_craft_type = function(name, def) - cg.craft_types[name] = def + cg.craft_types[name] = def end cg.register_group_stereotype = function(group, item) - cg.group_stereotypes[group] = item + cg.group_stereotypes[group] = item end minetest.register_on_mods_loaded(cg.build_item_list) diff --git a/autocrafting.lua b/autocrafting.lua index f2acd2c..0c13937 100644 --- a/autocrafting.lua +++ b/autocrafting.lua @@ -1,153 +1,153 @@ local add_or_create = function(t, i, n) - t[i] = t[i] and t[i] + n or n + t[i] = t[i] and t[i] + n or n end local get_group_item = function(invCache, groups) - local maxCount = 0 - local maxItem - local isInGroups - - for item, count in pairs(invCache) do - isInGroups = true - - for _, group in ipairs(groups) do - if minetest.get_item_group(item, group) == 0 then - isInGroups = false - break - end - end - - if isInGroups and count > maxCount then - maxItem = item - maxCount = count - end - end - - return maxItem + local maxCount = 0 + local maxItem + local isInGroups + + for item, count in pairs(invCache) do + isInGroups = true + + for _, group in ipairs(groups) do + if minetest.get_item_group(item, group) == 0 then + isInGroups = false + break + end + end + + if isInGroups and count > maxCount then + maxItem = item + maxCount = count + end + end + + return maxItem end cg.auto_get_craftable = function(player, craft) - local inv = player:get_inventory():get_list("main") - local invCache = {} - - -- Create a cache of the inventory with itemName = count pairs. This speeds up searching for items. - for _, stack in ipairs(inv) do - if stack:get_count() > 0 then - add_or_create(invCache, stack:get_name(), stack:get_count()) - end - end - - local reqItems = {} - local reqGroups = {} - - -- Find out how many of each item/group is required to craft one item. - for _, item in pairs(craft.items) do - if item:sub(1, 6) == "group:" then - add_or_create(reqGroups, item, 1) - else - add_or_create(reqItems, item, 1) - end - end - - local gMaxItem - - -- For each group, find the item in that group from the player's inventory with the largest count. - for group, count in pairs(reqGroups) do - gMaxItem = get_group_item(invCache, group:sub(7):split(",")) - - if gMaxItem then - add_or_create(reqItems, gMaxItem, count) - else - return 0 - end - end - - local craftable = 1000 - - for item, count in pairs(reqItems) do - if invCache[item] then - craftable = math.min(craftable, math.floor(invCache[item] / count)) - else - return 0 - end - - -- We can't craft more than the stack_max of our ingredients. - if minetest.registered_items[item].stack_max then - craftable = math.min(craftable, minetest.registered_items[item].stack_max) - end - end - - return craftable + local inv = player:get_inventory():get_list("main") + local invCache = {} + + -- Create a cache of the inventory with itemName = count pairs. This speeds up searching for items. + for _, stack in ipairs(inv) do + if stack:get_count() > 0 then + add_or_create(invCache, stack:get_name(), stack:get_count()) + end + end + + local reqItems = {} + local reqGroups = {} + + -- Find out how many of each item/group is required to craft one item. + for _, item in pairs(craft.items) do + if item:sub(1, 6) == "group:" then + add_or_create(reqGroups, item, 1) + else + add_or_create(reqItems, item, 1) + end + end + + local gMaxItem + + -- For each group, find the item in that group from the player's inventory with the largest count. + for group, count in pairs(reqGroups) do + gMaxItem = get_group_item(invCache, group:sub(7):split(",")) + + if gMaxItem then + add_or_create(reqItems, gMaxItem, count) + else + return 0 + end + end + + local craftable = 1000 + + for item, count in pairs(reqItems) do + if invCache[item] then + craftable = math.min(craftable, math.floor(invCache[item] / count)) + else + return 0 + end + + -- We can't craft more than the stack_max of our ingredients. + if minetest.registered_items[item].stack_max then + craftable = math.min(craftable, minetest.registered_items[item].stack_max) + end + end + + return craftable end cg.auto_craft = function(player, craft, num) - inv = player:get_inventory() - - if not inv:is_empty("craft") then - -- Attempt to move items to the player's main inventory. - for idx, stack in ipairs(inv:get_list("craft")) do - if not stack:is_empty() then - stack = inv:add_item("main", stack) - inv:set_stack("craft", idx, stack) - end - end - - -- Check again, and return if not all items were moved. - if not inv:is_empty("craft") then - minetest.chat_send_player(player:get_player_name(), cg.S("Item could not be crafted!")) - return - end - end - - if craft.width > inv:get_width("craft") or table.maxn(craft.items) > inv:get_size("craft") then return end - - local invList = inv:get_list("main") - local width = craft.width == 0 and inv:get_width("craft") or craft.width - local stack, invCache - local groupCache = {} - - for idx, item in pairs(craft.items) do - -- Shift the indices so the items in the craft go to the right spots on the crafting grid. - idx = idx + (inv:get_width("craft") - width) * math.floor((idx - 1) / width) - - if item:sub(1, 6) == "group:" then - -- Create an inventory cache. - if not invCache then - invCache = {} - - for _, stack in ipairs(invList) do - if stack:get_count() > 0 then - add_or_create(invCache, stack:get_name(), stack:get_count()) - end - end - end - - -- Get the most plentiful item in the group. - if not groupCache[item] then - groupCache[item] = get_group_item(invCache, item:sub(7):split(",")) - end - - -- Move the selected item. - if groupCache[item] then - stack = inv:remove_item("main", ItemStack({name = groupCache[item], count = num})) - inv:set_stack("craft", idx, stack) - end - else - -- Move the item. - stack = inv:remove_item("main", ItemStack({name = item, count = num})) - inv:set_stack("craft", idx, stack) - end - end + inv = player:get_inventory() + + if not inv:is_empty("craft") then + -- Attempt to move items to the player's main inventory. + for idx, stack in ipairs(inv:get_list("craft")) do + if not stack:is_empty() then + stack = inv:add_item("main", stack) + inv:set_stack("craft", idx, stack) + end + end + + -- Check again, and return if not all items were moved. + if not inv:is_empty("craft") then + minetest.chat_send_player(player:get_player_name(), cg.S("Item could not be crafted!")) + return + end + end + + if craft.width > inv:get_width("craft") or table.maxn(craft.items) > inv:get_size("craft") then return end + + local invList = inv:get_list("main") + local width = craft.width == 0 and inv:get_width("craft") or craft.width + local stack, invCache + local groupCache = {} + + for idx, item in pairs(craft.items) do + -- Shift the indices so the items in the craft go to the right spots on the crafting grid. + idx = idx + (inv:get_width("craft") - width) * math.floor((idx - 1) / width) + + if item:sub(1, 6) == "group:" then + -- Create an inventory cache. + if not invCache then + invCache = {} + + for _, stack in ipairs(invList) do + if stack:get_count() > 0 then + add_or_create(invCache, stack:get_name(), stack:get_count()) + end + end + end + + -- Get the most plentiful item in the group. + if not groupCache[item] then + groupCache[item] = get_group_item(invCache, item:sub(7):split(",")) + end + + -- Move the selected item. + if groupCache[item] then + stack = inv:remove_item("main", ItemStack({name = groupCache[item], count = num})) + inv:set_stack("craft", idx, stack) + end + else + -- Move the item. + stack = inv:remove_item("main", ItemStack({name = item, count = num})) + inv:set_stack("craft", idx, stack) + end + end end minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) - -- Hide the autocrafting menu when the player drops an item. - if cg.autocrafting and inventory_info.listname == "main" then - local context = sfinv.get_or_create_context(player) - - if context.cg_auto_menu then - context.cg_auto_menu = false - sfinv.set_player_inventory_formspec(player) - end - end + -- Hide the autocrafting menu when the player drops an item. + if cg.autocrafting and inventory_info.listname == "main" then + local context = sfinv.get_or_create_context(player) + + if context.cg_auto_menu then + context.cg_auto_menu = false + sfinv.set_player_inventory_formspec(player) + end + end end) diff --git a/init.lua b/init.lua index 55fe5a3..ae502ac 100644 --- a/init.lua +++ b/init.lua @@ -1,11 +1,11 @@ cg = { - PAGE_WIDTH = 8, - PAGE_ITEMS = 24, - items_all = {}, - items_filtered = {}, - crafts = {}, - craft_types = {}, - group_stereotypes = {}, + PAGE_WIDTH = 8, + PAGE_ITEMS = 24, + items_all = {}, + items_filtered = {}, + crafts = {}, + craft_types = {}, + group_stereotypes = {}, } local settings = minetest.settings @@ -22,100 +22,100 @@ local path = minetest.get_modpath("cg_plus") dofile(path .. "/api.lua") if cg.autocrafting then - dofile(path .. "/autocrafting.lua") + dofile(path .. "/autocrafting.lua") end dofile(path .. "/inventory.lua") cg.register_craft_type("normal", { - description = F(cg.S("Crafting")), - uses_crafting_grid = true, - alt_zero_width = "shapeless", - - get_grid_size = function(craft) - local width = math.max(craft.width, 1) - local height = math.ceil(table.maxn(craft.items) / width) - local sideLen = math.max(width, height) - - if sideLen < 3 then - return {x = 3, y = 3} - else - return {x = sideLen, y = sideLen} - end - end, + description = F(cg.S("Crafting")), + uses_crafting_grid = true, + alt_zero_width = "shapeless", + + get_grid_size = function(craft) + local width = math.max(craft.width, 1) + local height = math.ceil(table.maxn(craft.items) / width) + local sideLen = math.max(width, height) + + if sideLen < 3 then + return {x = 3, y = 3} + else + return {x = sideLen, y = sideLen} + end + end, }) cg.register_craft_type("shapeless", { - description = F(cg.S("Mixing")), - inherit_width = true, - uses_crafting_grid = true, - - get_grid_size = function(craft) - local numItems = table.maxn(craft.items) - - if table.maxn(craft.items) <= 9 then - return {x = 3, y = 3} - else - local sideLen = math.ceil(math.sqrt(numItems)) - return {x = sideLen, y = sideLen} - end - end, + description = F(cg.S("Mixing")), + inherit_width = true, + uses_crafting_grid = true, + + get_grid_size = function(craft) + local numItems = table.maxn(craft.items) + + if table.maxn(craft.items) <= 9 then + return {x = 3, y = 3} + else + local sideLen = math.ceil(math.sqrt(numItems)) + return {x = sideLen, y = sideLen} + end + end, }) cg.register_craft_type("cooking", { - description = F(cg.S("Cooking")), - inherit_width = true, - arrow_icon = "cg_plus_arrow_small.png^cg_plus_icon_cooking.png", + description = F(cg.S("Cooking")), + inherit_width = true, + arrow_icon = "cg_plus_arrow_small.png^cg_plus_icon_cooking.png", - get_grid_size = function(craft) - return {x = 1, y = 1} - end, + get_grid_size = function(craft) + return {x = 1, y = 1} + end, - get_infotext = function(craft) - return minetest.colorize("#FFFF00", F(cg.S("Time: @1 s", craft.width or 0))) - end, + get_infotext = function(craft) + return minetest.colorize("#FFFF00", F(cg.S("Time: @1 s", craft.width or 0))) + end, }) cg.register_craft_type("fuel", { - description = F(cg.S("Fuel")), - inherit_width = true, - arrow_icon = "cg_plus_arrow_small.png^cg_plus_icon_fuel.png", + description = F(cg.S("Fuel")), + inherit_width = true, + arrow_icon = "cg_plus_arrow_small.png^cg_plus_icon_fuel.png", - get_grid_size = function(craft) - return {x = 1, y = 1} - end, + get_grid_size = function(craft) + return {x = 1, y = 1} + end, - get_infotext = function(craft) - return minetest.colorize("#FFFF00", F(cg.S("Time: @1 s", craft.time or 0))) - end, + get_infotext = function(craft) + return minetest.colorize("#FFFF00", F(cg.S("Time: @1 s", craft.time or 0))) + end, }) cg.register_craft_type("digging", { - description = F(cg.S("Digging")), - inherit_width = true, - arrow_icon = "cg_plus_arrow_small.png^cg_plus_icon_digging.png", + description = F(cg.S("Digging")), + inherit_width = true, + arrow_icon = "cg_plus_arrow_small.png^cg_plus_icon_digging.png", - get_grid_size = function(craft) - return {x = 1, y = 1} - end, + get_grid_size = function(craft) + return {x = 1, y = 1} + end, }) cg.register_craft_type("digging_chance", { - description = F(cg.S("Digging@n(by chance)")), - inherit_width = true, - arrow_icon = "cg_plus_arrow_small.png^cg_plus_icon_digging.png", + description = F(cg.S("Digging@n(by chance)")), + inherit_width = true, + arrow_icon = "cg_plus_arrow_small.png^cg_plus_icon_digging.png", - get_grid_size = function(craft) - return {x = 1, y = 1} - end, + get_grid_size = function(craft) + return {x = 1, y = 1} + end, }) cg.register_group_stereotype("mesecon_conductor_craftable", "mesecons:wire_00000000_off") if minetest.get_modpath("default") then - cg.register_group_stereotype("stone", "default:stone") - cg.register_group_stereotype("wood", "default:wood") - cg.register_group_stereotype("sand", "default:sand") - cg.register_group_stereotype("leaves", "default:leaves") - cg.register_group_stereotype("tree", "default:tree") + cg.register_group_stereotype("stone", "default:stone") + cg.register_group_stereotype("wood", "default:wood") + cg.register_group_stereotype("sand", "default:sand") + cg.register_group_stereotype("leaves", "default:leaves") + cg.register_group_stereotype("tree", "default:tree") end diff --git a/inventory.lua b/inventory.lua index feee87d..20cd8d7 100644 --- a/inventory.lua +++ b/inventory.lua @@ -1,263 +1,263 @@ local F = minetest.formspec_escape cg.update_filter = function(player, context, filter, force) - if not force and (filter or "") == context.cg_filter then return end + if not force and (filter or "") == context.cg_filter then return end - context.cg_page = 0 - context.cg_filter = filter or "" - cg.filter_items(player, context.cg_filter) + context.cg_page = 0 + context.cg_filter = filter or "" + cg.filter_items(player, context.cg_filter) end cg.update_selected_item = function(player, context, item, force) - if not force and item == context.cg_selected_item then return end + if not force and item == context.cg_selected_item then return end - if item then context.cg_craft_page = 0 end + if item then context.cg_craft_page = 0 end - context.cg_selected_item = item - context.cg_auto_menu = false + context.cg_selected_item = item + context.cg_auto_menu = false end local make_item_button = function(formspec, x, y, size, name) - if name and name ~= "" then - local groups, buttonText - - if name:sub(1, 6) == "group:" then - groups = name:sub(7):split(",") - buttonText = #groups > 1 and ("G " .. #groups) or "G" - name = name:gsub(",", "/") - end - - formspec[#formspec + 1] = string.format("item_image_button[%.2f,%.2f;%.2f,%.2f;%s;cgitem_%s;%s]", - x, y, size, size, - groups and (cg.group_stereotypes[groups[1]] or "") or name, - name:match("^%S+"), -- Keep only the item name, not the quantity. - buttonText or "" - ) - - if groups then - formspec[#formspec + 1] = string.format("tooltip[cgitem_%s;%s]", - name, - #groups > 1 and - F(cg.S("Any item in groups: @1", minetest.colorize("#72FF63", table.concat(groups, ", ")))) or - F(cg.S("Any item in group: @1", minetest.colorize("#72FF63", groups[1]))) - ) - end - else - size = size * 0.8 + 0.2 - formspec[#formspec + 1] = string.format("image[%.2f,%.2f;%.2f,%.2f;gui_hb_bg.png]", x, y, size, size) - end + if name and name ~= "" then + local groups, buttonText + + if name:sub(1, 6) == "group:" then + groups = name:sub(7):split(",") + buttonText = #groups > 1 and ("G " .. #groups) or "G" + name = name:gsub(",", "/") + end + + formspec[#formspec + 1] = string.format("item_image_button[%.2f,%.2f;%.2f,%.2f;%s;cgitem_%s;%s]", + x, y, size, size, + groups and (cg.group_stereotypes[groups[1]] or "") or name, + name:match("^%S+"), -- Keep only the item name, not the quantity. + buttonText or "" + ) + + if groups then + formspec[#formspec + 1] = string.format("tooltip[cgitem_%s;%s]", + name, + #groups > 1 and + F(cg.S("Any item in groups: @1", minetest.colorize("#72FF63", table.concat(groups, ", ")))) or + F(cg.S("Any item in group: @1", minetest.colorize("#72FF63", groups[1]))) + ) + end + else + size = size * 0.8 + 0.2 + formspec[#formspec + 1] = string.format("image[%.2f,%.2f;%.2f,%.2f;gui_hb_bg.png]", x, y, size, size) + end end local make_item_grid = function(formspec, player, context) - local itemList = cg.get_item_list(player) - context.cg_page = context.cg_page or 0 - - formspec[#formspec + 1] = [[ - image_button[2.4,3.7;0.8,0.8;cg_plus_icon_search.png;cg_search;] - image_button[3.1,3.7;0.8,0.8;cg_plus_icon_clear.png;cg_clear;] - image_button[5.1,3.7;0.8,0.8;cg_plus_icon_prev.png;cg_prev;] - image_button[7.1,3.7;0.8,0.8;cg_plus_icon_next.png;cg_next;] - ]] - - formspec[#formspec + 1] = string.format("label[0,0;%s]", F(cg.S("Crafting Guide"))) - - formspec[#formspec + 1] = string.format("field[0.3,3.9;2.5,1;cg_filter;;%s]", F(context.cg_filter or "")) - formspec[#formspec + 1] = "field_close_on_enter[cg_filter;false]" - formspec[#formspec + 1] = string.format("label[6,3.8;%i / %i]", context.cg_page + 1, itemList.num_pages) - - local startIdx = context.cg_page * cg.PAGE_ITEMS + 1 - local item - - for itemIdx = 0, cg.PAGE_ITEMS - 1 do - item = itemList.list[startIdx + itemIdx] - - if item then - formspec[#formspec + 1] = string.format("item_image_button[%.2f,%.2f;1,1;%s;cgitem_%s;]", - itemIdx % cg.PAGE_WIDTH, - math.floor(itemIdx / cg.PAGE_WIDTH) + 0.5, - item, item - ) - end - end + local itemList = cg.get_item_list(player) + context.cg_page = context.cg_page or 0 + + formspec[#formspec + 1] = [[ + image_button[2.4,3.7;0.8,0.8;cg_plus_icon_search.png;cg_search;] + image_button[3.1,3.7;0.8,0.8;cg_plus_icon_clear.png;cg_clear;] + image_button[5.1,3.7;0.8,0.8;cg_plus_icon_prev.png;cg_prev;] + image_button[7.1,3.7;0.8,0.8;cg_plus_icon_next.png;cg_next;] + ]] + + formspec[#formspec + 1] = string.format("label[0,0;%s]", F(cg.S("Crafting Guide"))) + + formspec[#formspec + 1] = string.format("field[0.3,3.9;2.5,1;cg_filter;;%s]", F(context.cg_filter or "")) + formspec[#formspec + 1] = "field_close_on_enter[cg_filter;false]" + formspec[#formspec + 1] = string.format("label[6,3.8;%i / %i]", context.cg_page + 1, itemList.num_pages) + + local startIdx = context.cg_page * cg.PAGE_ITEMS + 1 + local item + + for itemIdx = 0, cg.PAGE_ITEMS - 1 do + item = itemList.list[startIdx + itemIdx] + + if item then + formspec[#formspec + 1] = string.format("item_image_button[%.2f,%.2f;1,1;%s;cgitem_%s;]", + itemIdx % cg.PAGE_WIDTH, + math.floor(itemIdx / cg.PAGE_WIDTH) + 0.5, + item, item + ) + end + end end local make_craft_preview = function(formspec, player, context) - formspec[#formspec + 1] = [[ - image_button[7.1,0.1;0.8,0.8;cg_plus_icon_prev.png;cg_craft_close;] - image[0.1,0.1;0.8,0.8;gui_hb_bg.png] - ]] - local item = context.cg_selected_item - - formspec[#formspec + 1] = string.format("item_image[0.1,0.1;0.8,0.8;%s]", item) - formspec[#formspec + 1] = string.format("label[1,0;%s]", - cg.crafts[item] and minetest.registered_items[item].description or item) - - local crafts = cg.crafts[item] - - if not crafts or #crafts == 0 then - formspec[#formspec + 1] = string.format("label[1,0.5;%s]", F(cg.S("There are no recipes for this item."))) - return - end - - if #crafts > 1 then - formspec[#formspec + 1] = [[ - image_button[1.85,3.7;0.8,0.8;cg_plus_icon_prev.png;cg_craft_prev;] - image_button[3.85,3.7;0.8,0.8;cg_plus_icon_next.png;cg_craft_next;] - ]] - formspec[#formspec + 1] = string.format("label[2.75,3.8;%i / %i]", context.cg_craft_page + 1, #crafts) - end - - local craft = cg.parse_craft(crafts[context.cg_craft_page + 1]) - local template = cg.craft_types[craft.type] or {} - - if cg.autocrafting and template.uses_crafting_grid then - formspec[#formspec + 1] = "image_button[0.1,3.7;0.8,0.8;cg_plus_icon_autocrafting.png;cg_auto_menu;]" - formspec[#formspec + 1] = string.format("tooltip[cg_auto_menu;%s]", F(cg.S("Craft this recipe"))) - - if context.cg_auto_menu then - local num = 1 - local yPos = 3 - - while true do - num = math.min(num, context.cg_auto_max) - formspec[#formspec + 1] = string.format("button[0.1,%.2f;0.8,0.8;cg_auto_%i;%i]", yPos, num, num) - formspec[#formspec + 1] = string.format( - "tooltip[cg_auto_%i;%s]", - num, - num == 1 and F(cg.S("Craft @1 item", num)) or F(cg.S("Craft @1 items", num)) - ) - - if num < context.cg_auto_max then - num = num * 10 - yPos = yPos - 0.7 - else - break - end - end - end - end - - formspec[#formspec + 1] = string.format("label[5,0.5;%s]", template.description or "") - formspec[#formspec + 1] = string.format("label[5,1;%s]", craft.infotext or "") - formspec[#formspec + 1] = string.format("image[4.75,1.5;1,1;%s]", - template.arrow_icon or "cg_plus_arrow.png") - - local slotSize = math.min(3 / math.max(craft.grid_size.x, craft.grid_size.y), 1) - local xOffset = 4.75 - craft.grid_size.x * slotSize - local yOffset = 2 - craft.grid_size.y * slotSize * 0.5 - - for idx = 1, craft.grid_size.x * craft.grid_size.y do - make_item_button(formspec, - (idx - 1) % craft.grid_size.x * slotSize + xOffset, - math.floor((idx - 1) / craft.grid_size.y) * slotSize + yOffset, - slotSize, - craft.items[idx] - ) - end - - make_item_button(formspec, 5.75, 1.5, 1, craft.output) + formspec[#formspec + 1] = [[ + image_button[7.1,0.1;0.8,0.8;cg_plus_icon_prev.png;cg_craft_close;] + image[0.1,0.1;0.8,0.8;gui_hb_bg.png] + ]] + local item = context.cg_selected_item + + formspec[#formspec + 1] = string.format("item_image[0.1,0.1;0.8,0.8;%s]", item) + formspec[#formspec + 1] = string.format("label[1,0;%s]", + cg.crafts[item] and minetest.registered_items[item].description or item) + + local crafts = cg.crafts[item] + + if not crafts or #crafts == 0 then + formspec[#formspec + 1] = string.format("label[1,0.5;%s]", F(cg.S("There are no recipes for this item."))) + return + end + + if #crafts > 1 then + formspec[#formspec + 1] = [[ + image_button[1.85,3.7;0.8,0.8;cg_plus_icon_prev.png;cg_craft_prev;] + image_button[3.85,3.7;0.8,0.8;cg_plus_icon_next.png;cg_craft_next;] + ]] + formspec[#formspec + 1] = string.format("label[2.75,3.8;%i / %i]", context.cg_craft_page + 1, #crafts) + end + + local craft = cg.parse_craft(crafts[context.cg_craft_page + 1]) + local template = cg.craft_types[craft.type] or {} + + if cg.autocrafting and template.uses_crafting_grid then + formspec[#formspec + 1] = "image_button[0.1,3.7;0.8,0.8;cg_plus_icon_autocrafting.png;cg_auto_menu;]" + formspec[#formspec + 1] = string.format("tooltip[cg_auto_menu;%s]", F(cg.S("Craft this recipe"))) + + if context.cg_auto_menu then + local num = 1 + local yPos = 3 + + while true do + num = math.min(num, context.cg_auto_max) + formspec[#formspec + 1] = string.format("button[0.1,%.2f;0.8,0.8;cg_auto_%i;%i]", yPos, num, num) + formspec[#formspec + 1] = string.format( + "tooltip[cg_auto_%i;%s]", + num, + num == 1 and F(cg.S("Craft @1 item", num)) or F(cg.S("Craft @1 items", num)) + ) + + if num < context.cg_auto_max then + num = num * 10 + yPos = yPos - 0.7 + else + break + end + end + end + end + + formspec[#formspec + 1] = string.format("label[5,0.5;%s]", template.description or "") + formspec[#formspec + 1] = string.format("label[5,1;%s]", craft.infotext or "") + formspec[#formspec + 1] = string.format("image[4.75,1.5;1,1;%s]", + template.arrow_icon or "cg_plus_arrow.png") + + local slotSize = math.min(3 / math.max(craft.grid_size.x, craft.grid_size.y), 1) + local xOffset = 4.75 - craft.grid_size.x * slotSize + local yOffset = 2 - craft.grid_size.y * slotSize * 0.5 + + for idx = 1, craft.grid_size.x * craft.grid_size.y do + make_item_button(formspec, + (idx - 1) % craft.grid_size.x * slotSize + xOffset, + math.floor((idx - 1) / craft.grid_size.y) * slotSize + yOffset, + slotSize, + craft.items[idx] + ) + end + + make_item_button(formspec, 5.75, 1.5, 1, craft.output) end sfinv.register_page("cg_plus:crafting_guide", { - title = "Crafting Guide", - get = function(self, player, context) - local formspec = {[[ - image[0,4.75;1,1;gui_hb_bg.png] - image[1,4.75;1,1;gui_hb_bg.png] - image[2,4.75;1,1;gui_hb_bg.png] - image[3,4.75;1,1;gui_hb_bg.png] - image[4,4.75;1,1;gui_hb_bg.png] - image[5,4.75;1,1;gui_hb_bg.png] - image[6,4.75;1,1;gui_hb_bg.png] - image[7,4.75;1,1;gui_hb_bg.png] - ]]} - - if context.cg_selected_item then - make_craft_preview(formspec, player, context) - else - make_item_grid(formspec, player, context) - end - - return sfinv.make_formspec(player, context, table.concat(formspec), true) - end, - - on_player_receive_fields = function(self, player, context, fields) - if fields.cg_craft_close then - context.cg_selected_item = nil - context.cg_auto_menu = false - elseif fields.cg_prev and context.cg_page then - context.cg_page = context.cg_page - 1 - elseif fields.cg_next and context.cg_page then - context.cg_page = context.cg_page + 1 - elseif fields.cg_craft_prev and context.cg_craft_page then - context.cg_craft_page = context.cg_craft_page - 1 - context.cg_auto_menu = false - elseif fields.cg_craft_next and context.cg_craft_page then - context.cg_craft_page = context.cg_craft_page + 1 - context.cg_auto_menu = false - elseif fields.cg_search or fields.key_enter_field == "cg_filter" then - cg.update_filter(player, context, fields.cg_filter) - elseif fields.cg_clear then - cg.update_filter(player, context, "", true) - elseif fields.cg_auto_menu and cg.autocrafting then - if not context.cg_auto_menu then - -- Make sure the craft is valid, in case the client is sending fake formspec fields. - local crafts = cg.crafts[context.cg_selected_item] or {} - local craft = crafts[context.cg_craft_page + 1] - - if craft and cg.craft_types[craft.type] and cg.craft_types[craft.type].uses_crafting_grid then - context.cg_auto_menu = true - context.cg_auto_max = cg.auto_get_craftable(player, craft) - end - else - context.cg_auto_menu = false - end - else - for field, _ in pairs(fields) do - if field:sub(1, 7) == "cgitem_" then - local item = string.sub(field, 8) - - if item:sub(1, 6) == "group:" then - if cg.group_search then - cg.update_filter(player, context, item:gsub("/", ",")) - cg.update_selected_item(player, context, nil) - elseif cg.group_stereotypes[item:sub(7)] then - cg.update_selected_item(player, context, cg.group_stereotypes[item:sub(7)]) - end - else - cg.update_selected_item(player, context, item) - end - - break - elseif field:sub(1, 8) == "cg_auto_" and context.cg_auto_menu then - -- No need to sanity check, we already did that when showing the autocrafting menu. - local num = tonumber(field:sub(9)) - - if num > 0 and num <= context.cg_auto_max then - cg.auto_craft(player, cg.crafts[context.cg_selected_item][context.cg_craft_page + 1], num) - sfinv.set_page(player, "sfinv:crafting") - end - - context.cg_auto_menu = false - break - end - end - end - - -- Wrap around when the player presses the next button on the last page, or the previous button on the first. - if context.cg_page then - context.cg_page = context.cg_page % math.max(cg.get_item_list(player).num_pages, 1) - end - - if context.cg_craft_page then - context.cg_craft_page = context.cg_craft_page % math.max(#(cg.crafts[context.cg_selected_item] or {}), 1) - end - - -- Update the formspec. - sfinv.set_player_inventory_formspec(player, context) - end, - - on_leave = function(self, player, context) - context.cg_auto_menu = false - end, + title = "Crafting Guide", + get = function(self, player, context) + local formspec = {[[ + image[0,4.75;1,1;gui_hb_bg.png] + image[1,4.75;1,1;gui_hb_bg.png] + image[2,4.75;1,1;gui_hb_bg.png] + image[3,4.75;1,1;gui_hb_bg.png] + image[4,4.75;1,1;gui_hb_bg.png] + image[5,4.75;1,1;gui_hb_bg.png] + image[6,4.75;1,1;gui_hb_bg.png] + image[7,4.75;1,1;gui_hb_bg.png] + ]]} + + if context.cg_selected_item then + make_craft_preview(formspec, player, context) + else + make_item_grid(formspec, player, context) + end + + return sfinv.make_formspec(player, context, table.concat(formspec), true) + end, + + on_player_receive_fields = function(self, player, context, fields) + if fields.cg_craft_close then + context.cg_selected_item = nil + context.cg_auto_menu = false + elseif fields.cg_prev and context.cg_page then + context.cg_page = context.cg_page - 1 + elseif fields.cg_next and context.cg_page then + context.cg_page = context.cg_page + 1 + elseif fields.cg_craft_prev and context.cg_craft_page then + context.cg_craft_page = context.cg_craft_page - 1 + context.cg_auto_menu = false + elseif fields.cg_craft_next and context.cg_craft_page then + context.cg_craft_page = context.cg_craft_page + 1 + context.cg_auto_menu = false + elseif fields.cg_search or fields.key_enter_field == "cg_filter" then + cg.update_filter(player, context, fields.cg_filter) + elseif fields.cg_clear then + cg.update_filter(player, context, "", true) + elseif fields.cg_auto_menu and cg.autocrafting then + if not context.cg_auto_menu then + -- Make sure the craft is valid, in case the client is sending fake formspec fields. + local crafts = cg.crafts[context.cg_selected_item] or {} + local craft = crafts[context.cg_craft_page + 1] + + if craft and cg.craft_types[craft.type] and cg.craft_types[craft.type].uses_crafting_grid then + context.cg_auto_menu = true + context.cg_auto_max = cg.auto_get_craftable(player, craft) + end + else + context.cg_auto_menu = false + end + else + for field, _ in pairs(fields) do + if field:sub(1, 7) == "cgitem_" then + local item = string.sub(field, 8) + + if item:sub(1, 6) == "group:" then + if cg.group_search then + cg.update_filter(player, context, item:gsub("/", ",")) + cg.update_selected_item(player, context, nil) + elseif cg.group_stereotypes[item:sub(7)] then + cg.update_selected_item(player, context, cg.group_stereotypes[item:sub(7)]) + end + else + cg.update_selected_item(player, context, item) + end + + break + elseif field:sub(1, 8) == "cg_auto_" and context.cg_auto_menu then + -- No need to sanity check, we already did that when showing the autocrafting menu. + local num = tonumber(field:sub(9)) + + if num > 0 and num <= context.cg_auto_max then + cg.auto_craft(player, cg.crafts[context.cg_selected_item][context.cg_craft_page + 1], num) + sfinv.set_page(player, "sfinv:crafting") + end + + context.cg_auto_menu = false + break + end + end + end + + -- Wrap around when the player presses the next button on the last page, or the previous button on the first. + if context.cg_page then + context.cg_page = context.cg_page % math.max(cg.get_item_list(player).num_pages, 1) + end + + if context.cg_craft_page then + context.cg_craft_page = context.cg_craft_page % math.max(#(cg.crafts[context.cg_selected_item] or {}), 1) + end + + -- Update the formspec. + sfinv.set_player_inventory_formspec(player, context) + end, + + on_leave = function(self, player, context) + context.cg_auto_menu = false + end, })