From a8c231da3479638e772823faa8a72b92f826544b Mon Sep 17 00:00:00 2001 From: kabou Date: Tue, 10 May 2022 18:28:57 +0200 Subject: [PATCH 01/10] Refactor compass code. * Split up `get_compass_image()` into smaller functions. This allows for better code sharing between old and new API and globalstep fn. * Add `get_compass_itemname()` function. It will be the new API of choice, `get_compass_image() will be deprecated soon. * Remove function declaration out of globalstep function. * Various other performance improvements. * Add local aliases for global functions * Lodestone compasses can only stack 1 item. * Document functions and variables. * Fix lodetone compass inaccurately reusing compass descriptions. * Add usage descriptions to node definitions * Refactor craftitem registration code. * Update translation templates. --- mods/ITEMS/mcl_compass/init.lua | 343 +++++++++++------- .../mcl_compass/locale/mcl_compass.de.tr | 7 +- .../mcl_compass/locale/mcl_compass.es.tr | 8 +- .../mcl_compass/locale/mcl_compass.fr.tr | 7 +- .../mcl_compass/locale/mcl_compass.pl.tr | 7 +- .../mcl_compass/locale/mcl_compass.ru.tr | 7 +- .../mcl_compass/locale/mcl_compass.zh_TW.tr | 7 +- mods/ITEMS/mcl_compass/locale/template.txt | 7 +- 8 files changed, 247 insertions(+), 146 deletions(-) diff --git a/mods/ITEMS/mcl_compass/init.lua b/mods/ITEMS/mcl_compass/init.lua index 91e9eb607d..5c237aeba8 100644 --- a/mods/ITEMS/mcl_compass/init.lua +++ b/mods/ITEMS/mcl_compass/init.lua @@ -1,16 +1,55 @@ -local stereotype_frame = 18 - - local S = minetest.get_translator(minetest.get_current_modname()) mcl_compass = {} +local compass_types = { + { + name = "compass", + desc = S("Compass"), + tt = S("Points to the world origin"), + longdesc = S("Compasses are tools which point to the world origin (X=0, Z=0) or the spawn point in the Overworld."), + usagehelp = S("A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly."), + }, + { + name = "compass_lodestone", + desc = S("Lodestone Compass"), + tt = S("Points to a lodestone"), + longdesc = S("Lodestone compasses resemble regular compasses, but they point to a specific lodestone."), + usagehelp = S("A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone."), + } +} + +-- Number of dynamic compass images (and items registered.) local compass_frames = 32 +-- The image/item that is craftable and shown in inventories. +local stereotype_frame = 18 + +-- random compass spinning tick in seconds. +-- Increase if there are performance problems. +local spin_timer_tick = 0.5 + +-- Local aliases to globals for better lua performance +local m_deg = math.deg +local m_atan2 = math.atan2 +local m_floor = math.floor +local m_rnd = math.random +local vec_new = vector.new +local vec_from_str = vector.from_string +local get_connected_players = minetest.get_connected_players +local get_item_group = minetest.get_item_group +local setting_get_pos = minetest.setting_get_pos +local compass_works = mcl_worlds.compass_works +local y_to_layer = mcl_worlds.y_to_layer + +-- Initialize random compass frame for spinning compass. It is updated in +-- the compass globalstep function. +local random_frame = m_rnd(0, compass_frames-1) + local function get_far_node(pos, itemstack) --code from minetest dev wiki: https://dev.minetest.net/minetest.get_node, some edits have been made to add a cooldown for force loads local node = minetest.get_node(pos) if node.name == "ignore" then - tstamp = tonumber(itemstack:get_meta():get_string("last_forceload")) + local tstamp = tonumber(itemstack:get_meta():get_string("last_forceload")) if tstamp == nil then --this is only relevant for new lodestone compasses, the ones that have never performes a forceload yet itemstack:get_meta():set_string("last_forceload", tostring(os.time(os.date("!*t")))) tstamp = tonumber(os.time(os.date("!*t"))) @@ -26,154 +65,180 @@ local function get_far_node(pos, itemstack) --code from minetest dev wiki: https return node end +--- Get compass needle angle. +-- Returns the angle that the compass needle should point at expressed in +-- 360 degrees divided by the number of possible compass image frames.. +-- +-- pos: position of the compass; +-- target: position that the needle points towards; +-- dir: rotational direction of the compass. +-- +local function get_compass_angle(pos, target, dir) + local angle_north = m_deg(m_atan2(target.x - pos.x, target.z - pos.z)) + if angle_north < 0 then angle_north = angle_north + 360 end + local angle_dir = -m_deg(dir) + local angle_relative = (angle_north - angle_dir + 180) % 360 + return m_floor((angle_relative/11.25) + 0.5) % compass_frames +end ---Not sure spawn point should be dymanic (is it in mc?) ---local default_spawn_settings = minetest.settings:get("static_spawnpoint") - --- Timer for random compass spinning -local random_timer = 0 -local random_timer_trigger = 0.5 -- random compass spinning tick in seconds. Increase if there are performance problems - -local random_frame = math.random(0, compass_frames-1) - -function mcl_compass.get_compass_image(pos, dir, itemstack) - if not itemstack then - minetest.log("WARNING: mcl_compass.get_compass_image() was called without itemstack, returning random frame!") - return random_frame - end - - local lodestone_pos = minetest.string_to_pos(itemstack:get_meta():get_string("pointsto")) - - if lodestone_pos then --lodestone meta present - local _, dim = mcl_worlds.y_to_layer(lodestone_pos.y) - local _, playerdim = mcl_worlds.y_to_layer(pos.y) - - if dim == playerdim then --Check if player and compass target are in the same dimension, above check is just if the diemension is valid for the non lodestone compass - - if get_far_node(lodestone_pos, itemstack).name == "mcl_compass:lodestone" then --check if lodestone still exists - local angle_north = math.deg(math.atan2(lodestone_pos.x - pos.x, lodestone_pos.z - pos.z)) - if angle_north < 0 then angle_north = angle_north + 360 end - local angle_dir = -math.deg(dir) - local angle_relative = (angle_north - angle_dir + 180) % 360 - return math.floor((angle_relative/11.25) + 0.5) % compass_frames .. "_lodestone" - else -- lodestone got destroyed - return random_frame .. "_lodestone" - end - else - return random_frame .. "_lodestone" - end - else --no lodestone meta, normal compass.... - local spawn = {x = 0, y=0, z=0} --before you guys tell me that the normal compass no points to real spawn, it always pointed to 0 0 - local ssp = minetest.setting_get_pos("static_spawnpoint") - if ssp then - spawn = ssp - if type(spawn) ~= "table" or type(spawn.x) ~= "number" or type(spawn.y) ~= "number" or type(spawn.z) ~= "number" then - spawn = {x=0,y=0,z=0} - end - end - - if mcl_worlds.compass_works(pos) then --is the player in the overworld? - local angle_north = math.deg(math.atan2(spawn.x - pos.x, spawn.z - pos.z)) - if angle_north < 0 then angle_north = angle_north + 360 end - local angle_dir = -math.deg(dir) - local angle_relative = (angle_north - angle_dir + 180) % 360 - return math.floor((angle_relative/11.25) + 0.5) % compass_frames +--- Get compass image frame. +-- Returns the compass image frame with the needle direction matching the +-- compass' current position. +-- +-- pos: position of the compass; +-- dir: rotational direction of the compass. +-- itemstack: the compass including its optional lodestone metadata. +-- +local function get_compass_frame(pos, dir, itemstack) + local lpos_str = itemstack:get_meta():get_string("pointsto") + if lpos_str == "" then -- normal compass + -- Compasses only work in the overworld + if compass_works(pos) then + local spawn_pos = setting_get_pos("static_spawnpoint") + or vec_new(0, 0, 0) + return get_compass_angle(pos, spawn_pos, dir) + else + return random_frame + end + else -- lodestone compass + local lpos = vec_from_str(lpos_str) + local _, l_dim = y_to_layer(lpos.y) + local _, p_dim = y_to_layer(pos.y) + -- compass and lodestone must be in the same dimension + if l_dim == p_dim then + --check if lodestone still exists + if get_far_node(lpos, itemstack).name == "mcl_compass:lodestone" then + return get_compass_angle(pos, lpos, dir) + else -- lodestone got destroyed + return random_frame + end else return random_frame end - end end -minetest.register_globalstep(function(dtime) - random_timer = random_timer + dtime - - if random_timer >= random_timer_trigger then - random_frame = (random_frame + math.random(-1, 1)) % compass_frames - random_timer = 0 +--- Get partial compass itemname. +-- Returns partial itemname of a compass with needle direction matching compass position. +-- Legacy compatibility function for mods using older api. +-- +function mcl_compass.get_compass_image(pos, dir, itemstack) + minetest.log("warning", "mcl_compass: deprecated function " .. + "get_compass_image() called, use get_compass_itemname().") + local itemstack = ItemStack("mcl_compass:" .. stereotype_frame) + local frame = get_compass_frame(pos, dir, itemstack) + if itemstack:get_meta():get_string("pointsto") ~= "" then + return frame .. "_lodestone" + else + return frame end - for _,player in pairs(minetest.get_connected_players()) do - local function has_compass(player) - for _,stack in pairs(player:get_inventory():get_list("main")) do - if minetest.get_item_group(stack:get_name(), "compass") ~= 0 then - return true - end - end - return false - end - if has_compass(player) then - local pos = player:get_pos() +end - for j,stack in pairs(player:get_inventory():get_list("main")) do - if minetest.get_item_group(stack:get_name(), "compass") ~= 0 then - local compass_image = mcl_compass.get_compass_image(pos, player:get_look_horizontal(), stack) - if minetest.get_item_group(stack:get_name(), "compass")-1 ~= compass_image and minetest.get_item_group(stack:get_name(), "compass")-1 .. "_lodestone" ~=compass_image then --Explaination: First check for normal compasses, secound check for lodestone ones - local itemname = "mcl_compass:"..compass_image - --minetest.log(os.time(os.date("!*t"))) - stack:set_name(itemname) - player:get_inventory():set_stack("main", j, stack) +--- Get compass itemname. +-- Returns the itemname of a compass with needle direction matching the +-- current compass position. +-- +-- pos: position of the compass; +-- dir: rotational orientation of the compass; +-- itemstack: the compass including its optional lodestone metadata. +-- +function mcl_compass.get_compass_itemname(pos, dir, itemstack) + if not itemstack then + minetest.log("warning", "mcl_compass.get_compass_image called without itemstack!") + return "mcl_compass:" .. stereotype_frame + end + local frame = get_compass_frame(pos, dir, itemstack) + if itemstack:get_meta():get_string("pointsto") ~= "" then + return "mcl_compass:" .. frame .. "_lodestone" + else + return "mcl_compass:" .. frame + end +end + +-- Timer for randomly spinning compass. +-- Gets updated and checked in the globalstep function. +local spin_timer = 0 + +-- Compass globalstep function. +-- * updates random spin counter and random frame of spinning compasses; +-- * updates all compasses in player's inventories to match the correct +-- needle orientations for their current positions. +-- +minetest.register_globalstep(function(dtime) + spin_timer = spin_timer + dtime + if spin_timer >= spin_timer_tick then + random_frame = (random_frame + m_rnd(-1, 1)) % compass_frames + spin_timer = 0 + end + + local compass_nr, compass_frame + local pos, dir, inv + for _, player in pairs(get_connected_players()) do + pos = player:get_pos() + dir = player:get_look_horizontal() + inv = player:get_inventory() + for j, stack in pairs(inv:get_list("main")) do + compass_nr = get_item_group(stack:get_name(), "compass") + if compass_nr ~= 0 then + -- check if current compass image still matches true orientation + compass_frame = get_compass_frame(pos, dir, stack) + if compass_nr - 1 ~= compass_frame then + if stack:get_meta():get_string("pointsto") == "" then + stack:set_name("mcl_compass:" .. compass_frame) + else + stack:set_name("mcl_compass:" .. compass_frame .. "_lodestone") end + inv:set_stack("main", j, stack) end - end end end end) -local images = {} -for frame = 0, compass_frames-1 do - local s = string.format("%02d", frame) - table.insert(images, "mcl_compass_compass_"..s..".png") -end - +-- +-- Node and craftitem definitions +-- local doc_mod = minetest.get_modpath("doc") -for i,img in ipairs(images) do - local inv = 1 - if i == stereotype_frame then - inv = 0 +for _, item in pairs(compass_types) do + local name_fmt, img_fmt, stack_max + if item.name == "compass" then + name_fmt = "mcl_compass:%d" + img_fmt = "mcl_compass_compass_%02d.png" + stack_max = 64 + elseif item.name == "compass_lodestone" then + name_fmt = "mcl_compass:%d_lodestone" + img_fmt = "mcl_compass_compass_%02d.png^[colorize:purple:50" + stack_max = 1 end - local use_doc, longdesc, tt - --Why is there no usage help? This should be fixed. - --local usagehelp - use_doc = i == stereotype_frame - if use_doc then - tt = S("Points to the world origin") - longdesc = S("Compasses are tools which point to the world origin (X=0, Z=0) or the spawn point in the Overworld.") - end - local itemstring = "mcl_compass:"..(i-1) - minetest.register_craftitem(itemstring, { - description = S("Compass"), - _tt_help = tt, - _doc_items_create_entry = use_doc, - _doc_items_longdesc = longdesc, - --_doc_items_usagehelp = usagehelp, - inventory_image = img, - wield_image = img, - stack_max = 64, - groups = {not_in_creative_inventory=inv, compass=i, tool=1, disable_repair=1 } - }) - - minetest.register_craftitem(itemstring .. "_lodestone", { - description = S("Lodestone Compass"), - _tt_help = tt, - _doc_items_create_entry = use_doc, - _doc_items_longdesc = longdesc, - --_doc_items_usagehelp = usagehelp, - inventory_image = img .. "^[colorize:purple:50", - wield_image = img .. "^[colorize:purple:50", - stack_max = 64, - groups = {not_in_creative_inventory=1, compass=i, tool=1, disable_repair=1 } - }) + for i = 0, compass_frames - 1 do + local def = { + description = item.desc, + _tt_help = item.tt, + inventory_image = string.format(img_fmt, i), + wield_image = string.format(img_fmt, i), + stack_max = stack_max, + groups = {compass = i + 1, tool = 1, disable_repair = 1}, + } + if i == stereotype_frame then + def._doc_items_longdesc = item.longdesc + def._doc_items_usagehelp = item.usagehelp + else + def._doc_items_create_entry = false + def.groups.not_in_creative_inventory = 1 + end + local itemstring = string.format(name_fmt, i) + minetest.register_craftitem(itemstring, table.copy(def)) - -- Help aliases. Makes sure the lookup tool works correctly - if not use_doc and doc_mod then - doc.add_entry_alias("craftitems", "mcl_compass:"..(stereotype_frame-1), "craftitems", itemstring) + -- Help aliases. Makes sure the lookup tool works correctly + if doc_mod and i ~= stereotype_frame then + doc.add_entry_alias("craftitems", "mcl_compass:"..(stereotype_frame), "craftitems", itemstring) + end end end minetest.register_craft({ - output = "mcl_compass:"..stereotype_frame, + output = "mcl_compass:" .. stereotype_frame, recipe = { {"", "mcl_core:iron_ingot", ""}, {"mcl_core:iron_ingot", "mesecons:redstone", "mcl_core:iron_ingot"}, @@ -181,19 +246,10 @@ minetest.register_craft({ } }) -minetest.register_craft({ - output = "mcl_compass:lodestone", - recipe = { - {"mcl_core:stonebrickcarved","mcl_core:stonebrickcarved","mcl_core:stonebrickcarved"}, - {"mcl_core:stonebrickcarved", "mcl_core:diamondblock", "mcl_core:stonebrickcarved"}, - {"mcl_core:stonebrickcarved", "mcl_core:stonebrickcarved", "mcl_core:stonebrickcarved"} - } -}) - -minetest.register_alias("mcl_compass:compass", "mcl_compass:"..stereotype_frame) +minetest.register_alias("mcl_compass:compass", "mcl_compass:" .. stereotype_frame) -- Export stereotype item for other mods to use -mcl_compass.stereotype = "mcl_compass:"..tostring(stereotype_frame) +mcl_compass.stereotype = "mcl_compass:" .. stereotype_frame minetest.register_node("mcl_compass:lodestone",{ @@ -218,3 +274,12 @@ minetest.register_node("mcl_compass:lodestone",{ _mcl_blast_resistance = 6, sounds = mcl_sounds.node_sound_stone_defaults() }) + +minetest.register_craft({ + output = "mcl_compass:lodestone", + recipe = { + {"mcl_core:stonebrickcarved","mcl_core:stonebrickcarved","mcl_core:stonebrickcarved"}, + {"mcl_core:stonebrickcarved", "mcl_core:diamondblock", "mcl_core:stonebrickcarved"}, + {"mcl_core:stonebrickcarved", "mcl_core:stonebrickcarved", "mcl_core:stonebrickcarved"} + } +}) diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr index cf4c814ceb..7be244b200 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr @@ -1,4 +1,9 @@ # textdomain: mcl_compass -Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Kompasse sind Werkzeuge, die zum Ursprungspunkt der Welt (X@=0, Z@=0) oder zum Einstiegspunkt der Welt zeigen. Compass=Kompass Points to the world origin=Zeigt zum Startpunkt der Welt +Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Kompasse sind Werkzeuge, die zum Ursprungspunkt der Welt (X@=0, Z@=0) oder zum Einstiegspunkt der Welt zeigen. +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.= +Lodestone Compass= +Points to a lodestone= +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.= +A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.= diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.es.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.es.tr index 4f9fd52948..77b36cad9f 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.es.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.es.tr @@ -1,3 +1,9 @@ # textdomain: mcl_compass +Compass=Brújula +Points to the world origin= Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Las brújulas son herramientas que apuntan al origen del mundo (X @ = 0, Z @ = 0) o al punto de generación en el mundo. -Compass=Brújula \ No newline at end of file +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.= +Lodestone Compass= +Points to a lodestone= +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.= +A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.= diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.fr.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.fr.tr index 89299fde7d..c09b334a02 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.fr.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.fr.tr @@ -1,4 +1,9 @@ # textdomain: mcl_compass -Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Les boussoles sont des outils qui pointent vers l'origine du monde (X@=0,Z@=0) ou le point d'apparition dans l'Overworld. Compass=Boussole Points to the world origin=Pointe vers l'origine mondiale +Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Les boussoles sont des outils qui pointent vers l'origine du monde (X@=0,Z@=0) ou le point d'apparition dans l'Overworld. +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.= +Lodestone Compass= +Points to a lodestone= +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.= +A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.= diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.pl.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.pl.tr index 2a95336525..33ac4b2044 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.pl.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.pl.tr @@ -1,4 +1,9 @@ # textdomain: mcl_compass -Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Kompasy to narzędzia które wskazują na punkt początku świata (X@=0, Z@=0) lub na miejsce odrodzenia na Powierzchni. Compass=Kompas Points to the world origin=Wskazuje na początek świata +Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Kompasy to narzędzia które wskazują na punkt początku świata (X@=0, Z@=0) lub na miejsce odrodzenia na Powierzchni. +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.= +Lodestone Compass= +Points to a lodestone= +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.= +A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.= diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.ru.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.ru.tr index dadf20c7de..7fd98de870 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.ru.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.ru.tr @@ -1,4 +1,9 @@ # textdomain: mcl_compass -Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Компас - инструмент, показывающий на начало мира (X@=0, Z@=0) или на точку возрождения в Верхнем Мире. Compass=Компас Points to the world origin=Указывает на начало мира +Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Компас - инструмент, показывающий на начало мира (X@=0, Z@=0) или на точку возрождения в Верхнем Мире. +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.= +Lodestone Compass= +Points to a lodestone= +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.= +A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.= diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.zh_TW.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.zh_TW.tr index b4a8126599..257487a553 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.zh_TW.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.zh_TW.tr @@ -1,4 +1,9 @@ # textdomain: mcl_compass -Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=指南針是指向世界原點(X@=0,Z@=0)或主世界的出生點的工具。 Compass=指南針 Points to the world origin=指向世界原點 +Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=指南針是指向世界原點(X@=0,Z@=0)或主世界的出生點的工具。 +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.= +Lodestone Compass= +Points to a lodestone= +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.= +A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.= diff --git a/mods/ITEMS/mcl_compass/locale/template.txt b/mods/ITEMS/mcl_compass/locale/template.txt index 462a08bc46..909e21a364 100644 --- a/mods/ITEMS/mcl_compass/locale/template.txt +++ b/mods/ITEMS/mcl_compass/locale/template.txt @@ -1,4 +1,9 @@ # textdomain: mcl_compass -Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.= Compass= Points to the world origin= +Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.= +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.= +Lodestone Compass= +Points to a lodestone= +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.= +A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.= From 8a4b8707fac599ba11e83d0586bc9d5acdea0b42 Mon Sep 17 00:00:00 2001 From: kabou Date: Tue, 10 May 2022 23:38:28 +0200 Subject: [PATCH 02/10] Add new compass API. * Add API.md * Update mcl_itemframes to use the new API. * Revert old exported function back to original API. --- mods/ITEMS/mcl_compass/API.md | 20 ++++++++++++++++++++ mods/ITEMS/mcl_compass/init.lua | 15 +++++---------- mods/ITEMS/mcl_itemframes/init.lua | 2 +- 3 files changed, 26 insertions(+), 11 deletions(-) create mode 100644 mods/ITEMS/mcl_compass/API.md diff --git a/mods/ITEMS/mcl_compass/API.md b/mods/ITEMS/mcl_compass/API.md new file mode 100644 index 0000000000..8a8e7247eb --- /dev/null +++ b/mods/ITEMS/mcl_compass/API.md @@ -0,0 +1,20 @@ +# mcl_compass + +# Compass API + +##mcl_compass.stereotype = "mcl_compass:" .. stereotype_frame +Default compass craftitem. This is also the image that is shown in the inventory. + +##mcl_compass/init.lua:function mcl_compass.get_compass_itemname(pos, dir, itemstack) +Returns the itemname of a compass with needle direction matching the +current compass position. + + pos: position of the compass; + dir: rotational orientation of the compass; + itemstack: the compass including its optional lodestone metadata. + +##mcl_compass/init.lua:function mcl_compass.get_compass_image(pos, dir) +-- Returns partial itemname of a compass with needle direction matching compass position. +-- Legacy compatibility function for mods using older api. + + diff --git a/mods/ITEMS/mcl_compass/init.lua b/mods/ITEMS/mcl_compass/init.lua index 5c237aeba8..89231709c6 100644 --- a/mods/ITEMS/mcl_compass/init.lua +++ b/mods/ITEMS/mcl_compass/init.lua @@ -118,20 +118,18 @@ local function get_compass_frame(pos, dir, itemstack) end end +-- Export stereotype item for other mods to use +mcl_compass.stereotype = "mcl_compass:" .. stereotype_frame + --- Get partial compass itemname. -- Returns partial itemname of a compass with needle direction matching compass position. -- Legacy compatibility function for mods using older api. -- -function mcl_compass.get_compass_image(pos, dir, itemstack) +function mcl_compass.get_compass_image(pos, dir) minetest.log("warning", "mcl_compass: deprecated function " .. "get_compass_image() called, use get_compass_itemname().") - local itemstack = ItemStack("mcl_compass:" .. stereotype_frame) + local itemstack = ItemStack(mcl_compass.stereotype) local frame = get_compass_frame(pos, dir, itemstack) - if itemstack:get_meta():get_string("pointsto") ~= "" then - return frame .. "_lodestone" - else - return frame - end end --- Get compass itemname. @@ -248,9 +246,6 @@ minetest.register_craft({ minetest.register_alias("mcl_compass:compass", "mcl_compass:" .. stereotype_frame) --- Export stereotype item for other mods to use -mcl_compass.stereotype = "mcl_compass:" .. stereotype_frame - minetest.register_node("mcl_compass:lodestone",{ description=S("Lodestone"), diff --git a/mods/ITEMS/mcl_itemframes/init.lua b/mods/ITEMS/mcl_itemframes/init.lua index e2cf9da624..364bffee6f 100644 --- a/mods/ITEMS/mcl_itemframes/init.lua +++ b/mods/ITEMS/mcl_itemframes/init.lua @@ -222,7 +222,7 @@ minetest.register_node("mcl_itemframes:item_frame",{ put_itemstack:set_count(1) local itemname = put_itemstack:get_name() if minetest.get_item_group(itemname, "compass") > 0 then - put_itemstack:set_name("mcl_compass:" .. mcl_compass.get_compass_image(pos, minetest.dir_to_yaw(minetest.facedir_to_dir(node.param2)), put_itemstack)) + put_itemstack:set_name(mcl_compass.get_compass_itemname(pos, minetest.dir_to_yaw(minetest.facedir_to_dir(node.param2)), put_itemstack)) end if minetest.get_item_group(itemname, "clock") > 0 then minetest.get_node_timer(pos):start(1.0) From bacc7613b55c4564c7f910e062ab510e4c51d135 Mon Sep 17 00:00:00 2001 From: kabou Date: Wed, 11 May 2022 17:41:10 +0200 Subject: [PATCH 03/10] Fix crash in mt 5.4 with vector ops. * `vector.from_string()` is not available in mt pre-5.5. Replace with `minetest.string_to_pos()`. --- mods/ITEMS/mcl_compass/init.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_compass/init.lua b/mods/ITEMS/mcl_compass/init.lua index 89231709c6..00a2d43b83 100644 --- a/mods/ITEMS/mcl_compass/init.lua +++ b/mods/ITEMS/mcl_compass/init.lua @@ -35,7 +35,7 @@ local m_atan2 = math.atan2 local m_floor = math.floor local m_rnd = math.random local vec_new = vector.new -local vec_from_str = vector.from_string +local string_to_pos = minetest.string_to_pos local get_connected_players = minetest.get_connected_players local get_item_group = minetest.get_item_group local setting_get_pos = minetest.setting_get_pos @@ -101,7 +101,11 @@ local function get_compass_frame(pos, dir, itemstack) return random_frame end else -- lodestone compass - local lpos = vec_from_str(lpos_str) + local lpos = string_to_pos(lpos_str) + if not lpos then + minetest.log("warning", "mcl_compass: invalid lodestone position!") + return random_frame + end local _, l_dim = y_to_layer(lpos.y) local _, p_dim = y_to_layer(pos.y) -- compass and lodestone must be in the same dimension From aca4aca79be7e4a3873a5edb85f29b966da87e82 Mon Sep 17 00:00:00 2001 From: kabou Date: Wed, 11 May 2022 17:43:57 +0200 Subject: [PATCH 04/10] Add German translation. * Add "de" (German) translation by chmodsayshello. --- mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr index 7be244b200..9e03665087 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr @@ -2,8 +2,8 @@ Compass=Kompass Points to the world origin=Zeigt zum Startpunkt der Welt Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Kompasse sind Werkzeuge, die zum Ursprungspunkt der Welt (X@=0, Z@=0) oder zum Einstiegspunkt der Welt zeigen. -A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.= -Lodestone Compass= -Points to a lodestone= -Lodestone compasses resemble regular compasses, but they point to a specific lodestone.= -A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.= +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.=Ein Kompass zeigt immer zum Weltspawn in der Oberwelt. In sämtlichen anderen Dimensionen dreht er sich zufällig. +Lodestone Compass=Leitstein Kompass +Points to a lodestone=Zeigt zu einem Leitstein +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.=Leitstein Kompasse ähneln normalen Kompassen, aber sie zeigen zu einen spezifischen Leitstein. +A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.=Ein Leitstein Kompass kann mit einem normalen Kompass erstellt werden indem man ihn auf einem Leitstein benutzt. Nachdem er ein Leitstein Kompass geworden ist, wird er immer zu seinem Leitstein zeigen, sofern sie in der selben Dimension sind. Wenn sie nicht in der selben Dimension sind, dreht sich der Leitstein Kompass zufällig, wie ein normaler Kompass außerhalb der Oberwelt. Ein Leitstein Kompass kann mit einem anderem Leitstein verknüpft werden. From 8ae605165b5ce7e87136b565cec6763782d41083 Mon Sep 17 00:00:00 2001 From: kabou Date: Wed, 11 May 2022 17:53:41 +0200 Subject: [PATCH 05/10] Fix lodestone compass stack_max. * Lodestone compasses are stackable. * Remove hardcoded `stack_max` setting, use default. --- mods/ITEMS/mcl_compass/init.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/mods/ITEMS/mcl_compass/init.lua b/mods/ITEMS/mcl_compass/init.lua index 00a2d43b83..4deb091707 100644 --- a/mods/ITEMS/mcl_compass/init.lua +++ b/mods/ITEMS/mcl_compass/init.lua @@ -207,11 +207,9 @@ for _, item in pairs(compass_types) do if item.name == "compass" then name_fmt = "mcl_compass:%d" img_fmt = "mcl_compass_compass_%02d.png" - stack_max = 64 elseif item.name == "compass_lodestone" then name_fmt = "mcl_compass:%d_lodestone" img_fmt = "mcl_compass_compass_%02d.png^[colorize:purple:50" - stack_max = 1 end for i = 0, compass_frames - 1 do local def = { @@ -219,7 +217,6 @@ for _, item in pairs(compass_types) do _tt_help = item.tt, inventory_image = string.format(img_fmt, i), wield_image = string.format(img_fmt, i), - stack_max = stack_max, groups = {compass = i + 1, tool = 1, disable_repair = 1}, } if i == stereotype_frame then From 14c882f9825eed1f5ca350b0b7d9e8b45a048e11 Mon Sep 17 00:00:00 2001 From: kabou Date: Wed, 11 May 2022 21:31:50 +0200 Subject: [PATCH 06/10] Fix lodestone compass meta handling. * The nature of a compass was being determined by looking at its meta. This caused lodestone compasses with unset meta to turn into regular compasses. Fixed by using string matching on the itemname. * Changed lodestone rightclick handler to explicitly set the correct name and frame of the compass used on it instead of waiting for globalstep to do this. --- mods/ITEMS/mcl_compass/init.lua | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/mods/ITEMS/mcl_compass/init.lua b/mods/ITEMS/mcl_compass/init.lua index 4deb091707..936e8fb938 100644 --- a/mods/ITEMS/mcl_compass/init.lua +++ b/mods/ITEMS/mcl_compass/init.lua @@ -35,6 +35,7 @@ local m_atan2 = math.atan2 local m_floor = math.floor local m_rnd = math.random local vec_new = vector.new +local string_find = string.find local string_to_pos = minetest.string_to_pos local get_connected_players = minetest.get_connected_players local get_item_group = minetest.get_item_group @@ -90,8 +91,7 @@ end -- itemstack: the compass including its optional lodestone metadata. -- local function get_compass_frame(pos, dir, itemstack) - local lpos_str = itemstack:get_meta():get_string("pointsto") - if lpos_str == "" then -- normal compass + if not string_find(itemstack:get_name(), "_lodestone") then -- normal compass -- Compasses only work in the overworld if compass_works(pos) then local spawn_pos = setting_get_pos("static_spawnpoint") @@ -101,6 +101,7 @@ local function get_compass_frame(pos, dir, itemstack) return random_frame end else -- lodestone compass + local lpos_str = itemstack:get_meta():get_string("pointsto") local lpos = string_to_pos(lpos_str) if not lpos then minetest.log("warning", "mcl_compass: invalid lodestone position!") @@ -185,10 +186,11 @@ minetest.register_globalstep(function(dtime) -- check if current compass image still matches true orientation compass_frame = get_compass_frame(pos, dir, stack) if compass_nr - 1 ~= compass_frame then - if stack:get_meta():get_string("pointsto") == "" then - stack:set_name("mcl_compass:" .. compass_frame) - else + + if string_find(stack:get_name(), "_lodestone") then stack:set_name("mcl_compass:" .. compass_frame .. "_lodestone") + else + stack:set_name("mcl_compass:" .. compass_frame) end inv:set_stack("main", j, stack) end @@ -251,9 +253,13 @@ minetest.register_alias("mcl_compass:compass", "mcl_compass:" .. stereotype_fram minetest.register_node("mcl_compass:lodestone",{ description=S("Lodestone"), on_rightclick = function(pos, node, player, itemstack) - if itemstack.get_name(itemstack).match(itemstack.get_name(itemstack),"mcl_compass:") then - if itemstack.get_name(itemstack) ~= "mcl_compass:lodestone" then + local name = itemstack.get_name(itemstack) + if string_find(name,"mcl_compass:") then + if name ~= "mcl_compass:lodestone" then itemstack:get_meta():set_string("pointsto", minetest.pos_to_string(pos)) + local dir = player:get_look_horizontal() + local frame = get_compass_frame(pos, dir, itemstack) + itemstack:set_name("mcl_compass:" .. frame .. "_lodestone") end end end, From 74e70b674efe332440634d782ee475acb3454da4 Mon Sep 17 00:00:00 2001 From: kabou Date: Wed, 11 May 2022 21:43:52 +0200 Subject: [PATCH 07/10] Fix return value of `get_compass_image()`. * `get_compass_image()` did not actually return the image number. --- mods/ITEMS/mcl_compass/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_compass/init.lua b/mods/ITEMS/mcl_compass/init.lua index 936e8fb938..55b46f6f49 100644 --- a/mods/ITEMS/mcl_compass/init.lua +++ b/mods/ITEMS/mcl_compass/init.lua @@ -134,7 +134,7 @@ function mcl_compass.get_compass_image(pos, dir) minetest.log("warning", "mcl_compass: deprecated function " .. "get_compass_image() called, use get_compass_itemname().") local itemstack = ItemStack(mcl_compass.stereotype) - local frame = get_compass_frame(pos, dir, itemstack) + return get_compass_frame(pos, dir, itemstack) end --- Get compass itemname. From 872b70846510f7f57a9122fa92a3567832104770 Mon Sep 17 00:00:00 2001 From: kabou Date: Wed, 11 May 2022 21:45:15 +0200 Subject: [PATCH 08/10] Remove unused variable. * Removed unused variable `stack_max`. --- mods/ITEMS/mcl_compass/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_compass/init.lua b/mods/ITEMS/mcl_compass/init.lua index 55b46f6f49..010d46a7f7 100644 --- a/mods/ITEMS/mcl_compass/init.lua +++ b/mods/ITEMS/mcl_compass/init.lua @@ -205,7 +205,7 @@ end) local doc_mod = minetest.get_modpath("doc") for _, item in pairs(compass_types) do - local name_fmt, img_fmt, stack_max + local name_fmt, img_fmt if item.name == "compass" then name_fmt = "mcl_compass:%d" img_fmt = "mcl_compass_compass_%02d.png" From 00dba67cd8d8c1811d1c1b662cc7f56c351c4f4c Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Thu, 12 May 2022 16:34:48 +0000 Subject: [PATCH 09/10] remove lodestone compass from creative inventory --- mods/ITEMS/mcl_compass/init.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_compass/init.lua b/mods/ITEMS/mcl_compass/init.lua index 010d46a7f7..0bcc3f0af9 100644 --- a/mods/ITEMS/mcl_compass/init.lua +++ b/mods/ITEMS/mcl_compass/init.lua @@ -214,6 +214,7 @@ for _, item in pairs(compass_types) do img_fmt = "mcl_compass_compass_%02d.png^[colorize:purple:50" end for i = 0, compass_frames - 1 do + local itemstring = string.format(name_fmt, i) local def = { description = item.desc, _tt_help = item.tt, @@ -224,11 +225,13 @@ for _, item in pairs(compass_types) do if i == stereotype_frame then def._doc_items_longdesc = item.longdesc def._doc_items_usagehelp = item.usagehelp + if string.match(itemstring, "lodestone") then + def.groups.not_in_creative_inventory = 1 + end else def._doc_items_create_entry = false def.groups.not_in_creative_inventory = 1 end - local itemstring = string.format(name_fmt, i) minetest.register_craftitem(itemstring, table.copy(def)) -- Help aliases. Makes sure the lookup tool works correctly From baf8e0b79c2c07d6af500d901aee4eae83a8c692 Mon Sep 17 00:00:00 2001 From: kabou Date: Thu, 12 May 2022 20:57:54 +0200 Subject: [PATCH 10/10] Update item entity for lodestone compass. * Added another special case to the item entity registration for lodestone compasses, without this a dropped lodestone compass would turn into a regular compass on being dropped. * Update the compass and lodestone compass frame number to be the stereotype frame. --- mods/ENTITIES/mcl_item_entity/init.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index e39e21bfb9..5d86071ebc 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -418,7 +418,11 @@ minetest.register_entity(":__builtin:item", { end local stack = ItemStack(itemstring) if minetest.get_item_group(stack:get_name(), "compass") > 0 then - stack:set_name("mcl_compass:16") + if string.find(stack:get_name(), "_lodestone") then + stack:set_name("mcl_compass:18_lodestone") + else + stack:set_name("mcl_compass:18") + end itemstring = stack:to_string() self.itemstring = itemstring end