From 549c697bc0cc479327c9989b7b00268d53682d0d Mon Sep 17 00:00:00 2001 From: flux <25628292+fluxionary@users.noreply.github.com> Date: Wed, 8 Feb 2023 12:07:24 -0800 Subject: [PATCH] remove dependency on futil --- api/register_machine.lua | 2 +- mod.conf | 3 +- modules/anvil/anvil.lua | 4 +- modules/barrel/barrel.lua | 4 +- modules/feldweg/api.lua | 2 +- modules/straw/quern.lua | 2 +- modules/straw/threshing.lua | 2 +- resources/craftitems.lua | 2 +- resources/textures.lua | 4 +- util.lua | 251 ++++++++++++++++++++++++++++++++++++ 10 files changed, 263 insertions(+), 13 deletions(-) diff --git a/api/register_machine.lua b/api/register_machine.lua index fb6998d..b4ca658 100644 --- a/api/register_machine.lua +++ b/api/register_machine.lua @@ -7,7 +7,7 @@ end local player_can_use = cottages.util.player_can_use local toggle_public = cottages.util.toggle_public -local items_equals = futil.items_equals +local items_equals = cottages.util.items_equals local api = { get_fs_parts_by_node_name = {}, diff --git a/mod.conf b/mod.conf index 2746cf3..f738a08 100644 --- a/mod.conf +++ b/mod.conf @@ -4,6 +4,5 @@ description = Contains a lot of blocks that fit to medieval settlements and smal author = Sokomine description = Contains nodes for building medieval houses. url = https://github.com/sokomine/cottages -version = 2022-09-29 -depends = futil +version = 2023-02-08 optional_depends = anvil, bucket, default, doors, env_sounds, ethereal, farming, moreblocks, node_entity_queue, player_api, player_monoids, stairs, stairsplus, stamina, technic, unified_inventory, wool, workbench diff --git a/modules/anvil/anvil.lua b/modules/anvil/anvil.lua index 2a2a397..b290744 100644 --- a/modules/anvil/anvil.lua +++ b/modules/anvil/anvil.lua @@ -15,8 +15,8 @@ local v_eq = vector.equals local v_new = vector.new local v_sub = vector.subtract -local get_safe_short_description = futil.get_safe_short_description -local resolve_item = futil.resolve_item +local get_safe_short_description = cottages.util.get_safe_short_description +local resolve_item = cottages.util.resolve_item local has_stamina = cottages.has.stamina diff --git a/modules/barrel/barrel.lua b/modules/barrel/barrel.lua index 0c46ff6..d840c7f 100644 --- a/modules/barrel/barrel.lua +++ b/modules/barrel/barrel.lua @@ -50,7 +50,7 @@ function barrel.get_barrel_fs_parts(pos) math.floor(max_liquid_amount * liquid_amount / max_liquid_amount), F( liquid_texture - .. futil.escape_texture(("^[resize:%ix%i"):format(max_liquid_amount, max_liquid_amount)) + .. cottages.util.escape_texture(("^[resize:%ix%i"):format(max_liquid_amount, max_liquid_amount)) ) ) ) @@ -76,7 +76,7 @@ function barrel.get_barrel_fs_parts(pos) 0, F( cottages.textures.furniture - .. futil.escape_texture(("^[resize:%ix%i"):format(max_liquid_amount, max_liquid_amount)) + .. cottages.util.escape_texture(("^[resize:%ix%i"):format(max_liquid_amount, max_liquid_amount)) ) ) ) diff --git a/modules/feldweg/api.lua b/modules/feldweg/api.lua index 65009d6..0d3ed6b 100644 --- a/modules/feldweg/api.lua +++ b/modules/feldweg/api.lua @@ -91,7 +91,7 @@ function api.register_feldweg(node, suffix, special) local def = minetest.registered_nodes[node] local texture_top, texture_bottom, texture_side, texture_side_with_dent, texture_edges = get_textures(def.tiles, special) - local desc = futil.get_safe_short_description(node) + local desc = cottages.util.get_safe_short_description(node) local feldweg_name = "cottages:feldweg" .. suffix register_feldweg(feldweg_name, def, { diff --git a/modules/straw/quern.lua b/modules/straw/quern.lua index 1f47fd1..0bb8975 100644 --- a/modules/straw/quern.lua +++ b/modules/straw/quern.lua @@ -6,7 +6,7 @@ local FS = function(...) return F(S(...)) end -local get_safe_short_description = futil.get_safe_short_description +local get_safe_short_description = cottages.util.get_safe_short_description local has_stamina = cottages.has.stamina local stamina_use = cottages.settings.straw.quern_stamina diff --git a/modules/straw/threshing.lua b/modules/straw/threshing.lua index 9257dd5..f8ce2bc 100644 --- a/modules/straw/threshing.lua +++ b/modules/straw/threshing.lua @@ -6,7 +6,7 @@ local FS = function(...) return F(S(...)) end -local get_safe_short_description = futil.get_safe_short_description +local get_safe_short_description = cottages.util.get_safe_short_description local has_stamina = cottages.has.stamina local stamina_use = cottages.settings.straw.threshing_stamina diff --git a/resources/craftitems.lua b/resources/craftitems.lua index b59d27a..f43a53b 100644 --- a/resources/craftitems.lua +++ b/resources/craftitems.lua @@ -1,6 +1,6 @@ local has = cottages.has -local resolve_item = futil.resolve_item +local resolve_item = cottages.util.resolve_item local ci = {} diff --git a/resources/textures.lua b/resources/textures.lua index a246714..f6198fb 100644 --- a/resources/textures.lua +++ b/resources/textures.lua @@ -1,6 +1,6 @@ local has = cottages.has -local check_exists = futil.check_exists +local item_exists = cottages.util.resolve_item local textures = {} @@ -27,7 +27,7 @@ if has.farming then textures.wheat_seed = "farming_wheat_seed.png" textures.wheat = "farming_wheat.png" - if cottages.settings.roof.use_farming_straw_stairs and check_exists("farming:straw") then + if cottages.settings.roof.use_farming_straw_stairs and item_exists("farming:straw") then textures.straw = "farming_straw.png" end end diff --git a/util.lua b/util.lua index a01a7eb..b9d88f3 100644 --- a/util.lua +++ b/util.lua @@ -1,3 +1,5 @@ +local f = string.format + local util = {} function util.player_can_use(pos, player) @@ -63,4 +65,253 @@ function util.toggle_public(pos, sender) return false end +local function tokenize(s) + local tokens = {} + + local i = 1 + local j = 1 + + while true do + if s:sub(j, j) == "" then + if i < j then + table.insert(tokens, s:sub(i, j - 1)) + end + return tokens + elseif s:sub(j, j):byte() == 27 then + if i < j then + table.insert(tokens, s:sub(i, j - 1)) + end + + i = j + local n = s:sub(i + 1, i + 1) + + if n == "(" then + local m = s:sub(i + 2, i + 2) + local k = s:find(")", i + 3, true) + if m == "T" then + table.insert(tokens, { + type = "translation", + domain = s:sub(i + 4, k - 1), + }) + elseif m == "c" then + table.insert(tokens, { + type = "color", + color = s:sub(i + 4, k - 1), + }) + elseif m == "b" then + table.insert(tokens, { + type = "bgcolor", + color = s:sub(i + 4, k - 1), + }) + else + error(("couldn't parse %s"):format(s)) + end + i = k + 1 + j = k + 1 + elseif n == "F" then + table.insert(tokens, { + type = "start", + }) + i = j + 2 + j = j + 2 + elseif n == "E" then + table.insert(tokens, { + type = "stop", + }) + i = j + 2 + j = j + 2 + else + error(("couldn't parse %s"):format(s)) + end + else + j = j + 1 + end + end +end + +local function parse(tokens, i, parsed) + parsed = parsed or {} + i = i or 1 + while i <= #tokens do + local token = tokens[i] + if type(token) == "string" then + table.insert(parsed, token) + i = i + 1 + elseif token.type == "color" or token.type == "bgcolor" then + table.insert(parsed, token) + i = i + 1 + elseif token.type == "translation" then + local contents = { + type = "translation", + domain = token.domain, + } + i = i + 1 + contents, i = parse(tokens, i, contents) + table.insert(parsed, contents) + elseif token.type == "start" then + local contents = { + type = "escape", + } + i = i + 1 + contents, i = parse(tokens, i, contents) + table.insert(parsed, contents) + elseif token.type == "stop" then + i = i + 1 + return parsed, i + else + error(("couldn't parse %s"):format(dump(token))) + end + end + return parsed, i +end + +local function erase_after_newline(parsed, erasing) + local single_line_parsed = {} + + for _, piece in ipairs(parsed) do + if type(piece) == "string" then + if not erasing then + if piece:find("\n") then + erasing = true + local single_line = piece:match("^([^\n]*)\n") + table.insert(single_line_parsed, single_line) + else + table.insert(single_line_parsed, piece) + end + end + elseif piece.type == "bgcolor" or piece.type == "color" then + table.insert(single_line_parsed, piece) + elseif piece.type == "escape" then + table.insert(single_line_parsed, erase_after_newline(piece, erasing)) + elseif piece.type == "translation" then + local stuff = erase_after_newline(piece, erasing) + stuff.domain = piece.domain + table.insert(single_line_parsed, stuff) + else + error(("unknown type %s"):format(piece.type)) + end + end + + return single_line_parsed +end + +local function unparse(parsed, parts) + parts = parts or {} + for _, part in ipairs(parsed) do + if type(part) == "string" then + table.insert(parts, part) + else + if part.type == "bgcolor" then + table.insert(parts, ("\27(b@%s)"):format(part.color)) + elseif part.type == "color" then + table.insert(parts, ("\27(c@%s)"):format(part.color)) + elseif part.domain then + table.insert(parts, ("\27(T@%s)"):format(part.domain)) + unparse(part, parts) + table.insert(parts, "\27E") + else + table.insert(parts, "\27F") + unparse(part, parts) + table.insert(parts, "\27E") + end + end + end + + return parts +end + +function util.get_safe_short_description(item) + item = type(item) == "userdata" and item or ItemStack(item) + local description = item:get_description() + local tokens = tokenize(description) + local parsed = parse(tokens) + local single_line_parsed = erase_after_newline(parsed) + local single_line = table.concat(unparse(single_line_parsed), "") + return single_line +end + +function util.resolve_item(item) + local item_stack = ItemStack(item) + local name = item_stack:get_name() + + local seen = { [name] = true } + + local alias = minetest.registered_aliases[name] + while alias do + name = alias + seen[name] = true + alias = minetest.registered_aliases[name] + if seen[alias] then + error(f("alias cycle on %s", name)) + end + end + + if minetest.registered_items[name] then + item_stack:set_name(name) + return item_stack:to_string() + end +end + +-- https://github.com/minetest/minetest/blob/9fc018ded10225589d2559d24a5db739e891fb31/doc/lua_api.txt#L453-L462 +function util.escape_texture(texturestring) + -- store in a variable so we don't return both rvs of gsub + local v = texturestring:gsub("[%^:]", { + ["^"] = "\\^", + [":"] = "\\:", + }) + return v +end + +function util.table_size(t) + local size = 0 + for _ in pairs(t) do + size = size + 1 + end + return size +end + +local function equals(a, b) + local t = type(a) + + if t ~= type(b) then + return false + end + + if t ~= "table" then + return a == b + elseif a == b then + return true + end + + local size_a = 0 + + for key, value in pairs(a) do + if not equals(value, b[key]) then + return false + end + size_a = size_a + 1 + end + + return size_a == util.table_size(b) +end + +util.equals = equals + +if ItemStack().equals then + -- https://github.com/minetest/minetest/pull/12771 + function util.items_equals(item1, item2) + item1 = type(item1) == "userdata" and item1 or ItemStack(item1) + item2 = type(item2) == "userdata" and item2 or ItemStack(item2) + + return item1 == item2 + end +else + function util.items_equals(item1, item2) + item1 = type(item1) == "userdata" and item1 or ItemStack(item1) + item2 = type(item2) == "userdata" and item2 or ItemStack(item2) + + return equals(item1:to_table(), item2:to_table()) + end +end + cottages.util = util