diff --git a/.luacheckrc b/.luacheckrc index 9d0b8cb2a..69c015665 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -1,10 +1,12 @@ +---@diagnostic disable + unused_args = false allow_defined_top = true max_line_length = false redefined = false globals = { - "minetest", "core", + "minetest", "core", } read_globals = { @@ -40,16 +42,16 @@ read_globals = { "factorial" } }, - ------ - --MODS - ------ + ------ + --MODS + ------ - --GENERAL - "default", + --GENERAL + "default", - --ENTITIES - "cmi", + --ENTITIES + "cmi", - --HUD - "sfinv", "sfinv_buttons", "unified_inventory", "cmsg", "inventory_plus", -} \ No newline at end of file + --HUD + "sfinv", "sfinv_buttons", "unified_inventory", "cmsg", "inventory_plus", +} diff --git a/.luarc.json b/.luarc.json new file mode 100644 index 000000000..7e9e92042 --- /dev/null +++ b/.luarc.json @@ -0,0 +1,22 @@ +{ + "runtime.version": "LuaJIT", + "diagnostics": { "disable": ["lowercase-global"] }, + "diagnostics.globals": [ + "minetest", + "dump", + "dump2", + "Raycast", + "Settings", + "PseudoRandom", + "PerlinNoise", + "VoxelManip", + "SecureRandom", + "VoxelArea", + "PerlinNoiseMap", + "PcgRandom", + "ItemStack", + "AreaStore", + "vector" + ], + "workspace.ignoreDir": [".luacheckrc"] +} diff --git a/mods/HUD/mcl_experience/init.lua b/mods/HUD/mcl_experience/init.lua index 359e68918..47e48d36c 100644 --- a/mods/HUD/mcl_experience/init.lua +++ b/mods/HUD/mcl_experience/init.lua @@ -147,13 +147,13 @@ function mcl_experience.throw_xp(pos, total_xp) obj:set_velocity(vector.new( math.random(-2, 2) * math.random(), - math.random( 2, 5), + math.random(2, 5), math.random(-2, 2) * math.random() )) i = i + xp j = j + 1 - table.insert(obs,obj) + table.insert(obs, obj) end return obs end @@ -179,18 +179,18 @@ function mcl_experience.setup_hud(player) if not minetest.is_creative_enabled(player:get_player_name()) then hud_bars[player] = player:hud_add({ hud_elem_type = "image", - position = {x = 0.5, y = 1}, - offset = {x = (-9 * 28) - 3, y = -(48 + 24 + 16 - 5)}, - scale = {x = 0.35, y = 0.375}, - alignment = {x = 1, y = 1}, + position = { x = 0.5, y = 1 }, + offset = { x = (-9 * 28) - 3, y = -(48 + 24 + 16 - 5) }, + scale = { x = 0.35, y = 0.375 }, + alignment = { x = 1, y = 1 }, z_index = 11, }) hud_levels[player] = player:hud_add({ hud_elem_type = "text", - position = {x = 0.5, y = 1}, + position = { x = 0.5, y = 1 }, number = 0x80FF20, - offset = {x = 0, y = -(48 + 24 + 24)}, + offset = { x = 0, y = -(48 + 24 + 24) }, z_index = 12, }) end @@ -221,7 +221,7 @@ function mcl_experience.update(player) end function mcl_experience.register_on_add_xp(func, priority) - table.insert(mcl_experience.on_add_xp, {func = func, priority = priority or 0}) + table.insert(mcl_experience.on_add_xp, { func = func, priority = priority or 0 }) end -- callbacks @@ -232,9 +232,9 @@ minetest.register_on_joinplayer(function(player) end) minetest.register_on_leaveplayer(function(player) - hud_bars[player] = nil - hud_levels[player] = nil - caches[player] = nil + hud_bars[player] = nil + hud_levels[player] = nil + caches[player] = nil end) minetest.register_on_dieplayer(function(player) @@ -247,3 +247,12 @@ end) minetest.register_on_mods_loaded(function() table.sort(mcl_experience.on_add_xp, function(a, b) return a.priority < b.priority end) end) + +mcl_gamemode.register_on_gamemode_change(function(player, old_gamemode, new_gamemode) + if new_gamemode == "survival" then + mcl_experience.setup_hud(player) + mcl_experience.update(player) + elseif new_gamemode == "creative" then + mcl_experience.remove_hud(player) + end +end) diff --git a/mods/HUD/mcl_experience/mod.conf b/mods/HUD/mcl_experience/mod.conf index 211249b30..a8e992c06 100644 --- a/mods/HUD/mcl_experience/mod.conf +++ b/mods/HUD/mcl_experience/mod.conf @@ -1,3 +1,4 @@ name = mcl_experience author = oilboi description = eXPerience mod +depends = mcl_gamemode diff --git a/mods/HUD/mcl_formspec/API.md b/mods/HUD/mcl_formspec/API.md new file mode 100644 index 000000000..64795f8c3 --- /dev/null +++ b/mods/HUD/mcl_formspec/API.md @@ -0,0 +1,40 @@ +# MineClone2 Formspec API + +## `mcl_formspec.label_color` + +Contains the color used for formspec labels, currently `#313131`. + +## `mcl_formspec.get_itemslot_bg(x, y, w, h)` + +Get the background of inventory slots (formspec version = 1) + +ex: + +```lua +local formspec = table.concat({ + mcl_formspec.get_itemslot_bg(0, 0, 5, 2), + "list[current_player;super_inventory;0,0;5,2;]", +}) +``` + +## `mcl_formspec.get_itemslot_bg_v4(x, y, w, h, size, texture)` + +Get the background of inventory slots (formspec version > 1) + +Works basically the same as `mcl_formspec.get_itemslot_bg(x, y, w, h)` but have more customisation options: + +- `size`: allow you to customize the size of the slot borders, default is 0.05 +- `texture`: allow you to specify a custom texture tu use instead of the default one + +ex: + +```lua +local formspec = table.concat({ + mcl_formspec.get_itemslot_bg_v4(0.375, 0.375, 5, 2, 0.1, "super_slot_background.png"), + "list[current_player;super_inventory;0.375,0.375;5,2;]", +}) +``` + +## `mcl_formspec.itemslot_border_size` + +Contains the default item slot border size used by `mcl_formspec.get_itemslot_bg_v4`, currently 0.05 diff --git a/mods/HUD/mcl_formspec/FORMSPEC_GUIDE.md b/mods/HUD/mcl_formspec/FORMSPEC_GUIDE.md new file mode 100644 index 000000000..a5f3d4745 --- /dev/null +++ b/mods/HUD/mcl_formspec/FORMSPEC_GUIDE.md @@ -0,0 +1,21 @@ +# MineClone2 Formspec Guide + +**_This guide will teach you the rules for creating formspecs for the MineClone2 game._** + +Formspecs are an important part of game and mod development. + +First of all, MineClone2 aims to support ONLY last formspec version. Many utility functions will not work with formspec v1 or v2. + +The typical width of an 9 slots width inventory formspec is `0.375 + 9 + ((9-1) * 0.25) + 0.375 = 11.75` + +Margins are 0.375. + +The labels color is `mcl_formspec.label_color` + +Space between 1st inventory line and the rest of inventory is 0.45 + +Labels should have 0.375 space above if there is no other stuff above and 0.45 between content + +- 0.375 under + +According to minetest modding book, table.concat is faster than string concatenation, so this method should be prefered (the code is also more clear) diff --git a/mods/HUD/mcl_formspec/init.lua b/mods/HUD/mcl_formspec/init.lua index 7013fc0ee..d449e937f 100644 --- a/mods/HUD/mcl_formspec/init.lua +++ b/mods/HUD/mcl_formspec/init.lua @@ -1,10 +1,55 @@ mcl_formspec = {} +mcl_formspec.label_color = "#313131" + +---Get the background of inventory slots (formspec version = 1) +---@param x number +---@param y number +---@param w number +---@param h number +---@return string function mcl_formspec.get_itemslot_bg(x, y, w, h) local out = "" for i = 0, w - 1, 1 do for j = 0, h - 1, 1 do - out = out .."image["..x+i..","..y+j..";1,1;mcl_formspec_itemslot.png]" + out = out .. "image[" .. x + i .. "," .. y + j .. ";1,1;mcl_formspec_itemslot.png]" + end + end + return out +end + +---This function will replace mcl_formspec.get_itemslot_bg then every formspec will be upgrade to version 4 +---@param x number +---@param y number +---@param size number +---@param texture? string +---@return string +---@nodiscard +local function get_slot(x, y, size, texture) + local t = "image[" .. x - size .. "," .. y - size .. ";" .. 1 + (size * 2) .. + "," .. 1 + (size * 2) .. ";" .. (texture and texture or "mcl_formspec_itemslot.png") .. "]" + return t +end + +mcl_formspec.itemslot_border_size = 0.05 + +---Get the background of inventory slots (formspec version > 1) +---@param x number +---@param y number +---@param w integer +---@param h integer +---@param size? number Optional size of the slot border (default: 0.05) +---@param texture? string Optional texture to replace the default one +---@return string +---@nodiscard +function mcl_formspec.get_itemslot_bg_v4(x, y, w, h, size, texture) + if not size then + size = mcl_formspec.itemslot_border_size + end + local out = "" + for i = 0, w - 1, 1 do + for j = 0, h - 1, 1 do + out = out .. get_slot(x + i + (i * 0.25), y + j + (j * 0.25), size, texture) end end return out diff --git a/mods/HUD/mcl_inventory/API.md b/mods/HUD/mcl_inventory/API.md new file mode 100644 index 000000000..5fc5a8d6e --- /dev/null +++ b/mods/HUD/mcl_inventory/API.md @@ -0,0 +1,35 @@ +# `mcl_inventory` + +## `mcl_inventory.register_survival_inventory_tab(def)` + +```lua +mcl_inventory.register_survival_inventory_tab({ + -- Page identifier + -- Used to uniquely identify the tab + id = "test", + + -- The tab description, can be translated + description = "Test", + + -- The name of the item that will be used as icon + item_icon = "mcl_core:stone", + + -- If true, the main inventory will be shown at the bottom of the tab + -- Listrings need to be added by hand + show_inventory = true, + + -- This function must return the tab's formspec for the player + build = function(player) + return "label[1,1;Hello hello]button[2,2;2,2;Hello;hey]" + end, + + -- This function will be called in the on_player_receive_fields callback if the tab is currently open + handle = function(player, fields) + print(dump(fields)) + end, + + -- This function will be called to know if a player can see the tab + -- Returns true by default + access = function(player) + end, +``` diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index 32bb226f0..bb2f226a2 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -3,19 +3,35 @@ local F = minetest.formspec_escape local C = minetest.colorize -- Prepare player info table +---@type table local players = {} -- Containing all the items for each Creative Mode tab +---@type table local inventory_lists = {} ---local mod_player = minetest.get_modpath("mcl_player") - -- Create tables -local builtin_filter_ids = {"blocks","deco","redstone","rail","food","tools","combat","mobs","brew","matr","misc","all"} +---@type string[] +local builtin_filter_ids = { + "blocks", + "deco", + "redstone", + "rail", + "food", + "tools", + "combat", + "mobs", + "brew", + "matr", + "misc", + "all" +} + for _, f in pairs(builtin_filter_ids) do inventory_lists[f] = {} end +---@param tbl string[] local function replace_enchanted_books(tbl) for k, item in ipairs(tbl) do if item:find("mcl_enchanting:book_enchanted") == 1 then @@ -28,20 +44,32 @@ local function replace_enchanted_books(tbl) end end ---[[ Populate all the item tables. We only do this once. Note this code must be -executed after loading all the other mods in order to work. ]] +-- Populate all the item tables. We only do this once. +-- Note this code must be executed after loading all the other mods in order to work. minetest.register_on_mods_loaded(function() - for name,def in pairs(minetest.registered_items) do - if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then + for name, def in pairs(minetest.registered_items) do + if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and + def.description ~= "" then + ---@param def mt.ItemDef|mt.NodeDef local function is_redstone(def) - return def.mesecons or def.groups.mesecon or def.groups.mesecon_conductor_craftable or def.groups.mesecon_effecor_off + return def.mesecons or def.groups.mesecon or def.groups.mesecon_conductor_craftable or + def.groups.mesecon_effecor_off end + + ---@param def mt.ItemDef|mt.NodeDef local function is_tool(def) return def.groups.tool or (def.tool_capabilities and def.tool_capabilities.damage_groups == nil) end + + ---@param def mt.ItemDef|mt.NodeDef local function is_weapon_or_armor(def) - return def.groups.weapon or def.groups.weapon_ranged or def.groups.ammo or def.groups.combat_item or ((def.groups.armor_head or def.groups.armor_torso or def.groups.armor_legs or def.groups.armor_feet or def.groups.horse_armor) and def.groups.non_combat_armor ~= 1) + return def.groups.weapon or def.groups.weapon_ranged or def.groups.ammo or def.groups.combat_item or + ( + ( + def.groups.armor_head or def.groups.armor_torso or def.groups.armor_legs or def.groups.armor_feet or + def.groups.horse_armor) and def.groups.non_combat_armor ~= 1) end + -- Is set to true if it was added in any category besides misc local nonmisc = false if def.groups.building_block then @@ -110,6 +138,11 @@ minetest.register_on_mods_loaded(function() end end) +---@param name string +---@param description string +---@param lang mt.LangCode +---@param filter string +---@return integer local function filter_item(name, description, lang, filter) local desc if not lang then @@ -120,13 +153,16 @@ local function filter_item(name, description, lang, filter) return string.find(name, filter, nil, true) or string.find(desc, filter, nil, true) end +---@param filter string +---@param player mt.PlayerObjectRef local function set_inv_search(filter, player) local playername = player:get_player_name() - local inv = minetest.get_inventory({type="detached", name="creative_"..playername}) + local inv = minetest.get_inventory({ type = "detached", name = "creative_" .. playername }) local creative_list = {} local lang = minetest.get_player_information(playername).lang_code - for name,def in pairs(minetest.registered_items) do - if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then + for name, def in pairs(minetest.registered_items) do + if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and + def.description ~= "" then if filter_item(string.lower(def.name), def.description, lang, filter) then table.insert(creative_list, name) end @@ -147,9 +183,11 @@ local function set_inv_search(filter, player) inv:set_list("main", creative_list) end +---@param page string +---@param player mt.PlayerObjectRef local function set_inv_page(page, player) local playername = player:get_player_name() - local inv = minetest.get_inventory({type="detached", name="creative_"..playername}) + local inv = minetest.get_inventory({ type = "detached", name = "creative_" .. playername }) inv:set_size("main", 0) local creative_list = {} if inventory_lists[page] then -- Standard filter @@ -160,9 +198,11 @@ local function set_inv_page(page, player) inv:set_list("main", creative_list) end + +---@param player mt.PlayerObjectRef local function init(player) local playername = player:get_player_name() - minetest.create_detached_inventory("creative_"..playername, { + minetest.create_detached_inventory("creative_" .. playername, { allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) if minetest.is_creative_enabled(playername) then return count @@ -197,24 +237,45 @@ local trash = minetest.create_detached_inventory("trash", { inv:set_stack(listname, index, "") end, }) + trash:set_size("main", 1) -local noffset = {} -- numeric tab offset -local offset = {} -- string offset: -local boffset = {} -- -local hoch = {} -local filtername = {} ---local bg = {} +------------------------------ +-- Formspec Precalculations -- +------------------------------ -local noffset_x_start = -0.24 +-- Numeric position of tab background image, indexed by tab name +---@type table +local noffset = {} + +-- String position of tab button background image, indexed by tab name +---@type table +local offset = {} + +-- String position of tab button, indexed by tab name +---@type table +local boffset = {} + +-- Used to determine the tab button background image +---@type table +local button_bg_postfix = {} + +-- Tab caption/tooltip translated string, indexed by tab name +---@type table +local filtername = {} + +local noffset_x_start = 0.2 local noffset_x = noffset_x_start -local noffset_y = -0.25 +local noffset_y = -1.34 + +---@param id string +---@param right? boolean local function next_noffset(id, right) if right then - noffset[id] = { 8.94, noffset_y } + noffset[id] = { 11.3, noffset_y } else noffset[id] = { noffset_x, noffset_y } - noffset_x = noffset_x + 1.25 + noffset_x = noffset_x + 1.6 end end @@ -228,7 +289,7 @@ next_noffset("misc") next_noffset("nix", true) noffset_x = noffset_x_start -noffset_y = 8.12 +noffset_y = 8.64 -- Lower row next_noffset("food") @@ -238,25 +299,25 @@ next_noffset("mobs") next_noffset("matr") next_noffset("inv", true) -for k,v in pairs(noffset) do +for k, v in pairs(noffset) do offset[k] = tostring(v[1]) .. "," .. tostring(v[2]) - boffset[k] = tostring(v[1]+0.19) .. "," .. tostring(v[2]+0.25) + boffset[k] = tostring(v[1] + 0.24) .. "," .. tostring(v[2] + 0.25) end -hoch["blocks"] = "" -hoch["deco"] = "" -hoch["redstone"] = "" -hoch["rail"] = "" -hoch["brew"] = "" -hoch["misc"] = "" -hoch["nix"] = "" -hoch["default"] = "" -hoch["food"] = "_down" -hoch["tools"] = "_down" -hoch["combat"] = "_down" -hoch["mobs"] = "_down" -hoch["matr"] = "_down" -hoch["inv"] = "_down" +button_bg_postfix["blocks"] = "" +button_bg_postfix["deco"] = "" +button_bg_postfix["redstone"] = "" +button_bg_postfix["rail"] = "" +button_bg_postfix["brew"] = "" +button_bg_postfix["misc"] = "" +button_bg_postfix["nix"] = "" +button_bg_postfix["default"] = "" +button_bg_postfix["food"] = "_down" +button_bg_postfix["tools"] = "_down" +button_bg_postfix["combat"] = "_down" +button_bg_postfix["mobs"] = "_down" +button_bg_postfix["matr"] = "_down" +button_bg_postfix["inv"] = "_down" filtername["blocks"] = S("Building Blocks") filtername["deco"] = S("Decoration Blocks") @@ -291,197 +352,252 @@ filtername["inv"] = S("Survival Inventory") bg["default"] = dark_bg end]] +-- Item name representing a tab, indexed by tab name +---@type table +local tab_icon = { + blocks = "mcl_core:brick_block", + deco = "mcl_flowers:peony", + redstone = "mesecons:redstone", + rail = "mcl_minecarts:golden_rail", + misc = "mcl_buckets:bucket_lava", + nix = "mcl_compass:compass", + food = "mcl_core:apple", + tools = "mcl_core:axe_iron", + combat = "mcl_core:sword_gold", + mobs = "mobs_mc:cow", + brew = "mcl_potions:dragon_breath", + matr = "mcl_core:stick", + inv = "mcl_chests:chest", +} + +-- Get the player configured stack size when taking items from creative inventory +---@param player mt.PlayerObjectRef +---@return integer local function get_stack_size(player) return player:get_meta():get_int("mcl_inventory:switch_stack") end +-- Set the player configured stack size when taking items from creative inventory +---@param player mt.PlayerObjectRef +---@param n integer local function set_stack_size(player, n) player:get_meta():set_int("mcl_inventory:switch_stack", n) end -minetest.register_on_joinplayer(function (player) +minetest.register_on_joinplayer(function(player) if get_stack_size(player) == 0 then set_stack_size(player, 64) end end) +---@param player mt.PlayerObjectRef function mcl_inventory.set_creative_formspec(player) local playername = player:get_player_name() if not players[playername] then return end local start_i = players[playername].start_i - local pagenum = start_i / (9*5) + 1 - local name = players[playername].page + local pagenum = start_i / (9 * 5) + 1 + local page = players[playername].page local inv_size = players[playername].inv_size local filter = players[playername].filter - local pagemax = math.max(1, math.floor((inv_size-1) / (9*5) + 1)) + + if not inv_size then + if page == "nix" then + local inv = minetest.get_inventory({ type = "detached", name = "creative_" .. playername }) + inv_size = inv:get_size("main") + elseif page and page ~= "inv" then + inv_size = #(inventory_lists[page]) + else + inv_size = 0 + end + end + local pagemax = math.max(1, math.floor((inv_size - 1) / (9 * 5) + 1)) + local name = "nix" local main_list - local listrings = "listring[detached:creative_"..playername..";main]".. - "listring[current_player;main]".. - "listring[detached:trash;main]" + local listrings = table.concat({ + "listring[detached:creative_" .. playername .. ";main]", + "listring[current_player;main]", + "listring[detached:trash;main]", + }) + + if page then + name = page + if players[playername] then + players[playername].page = page + end + end - local inv_bg = "crafting_inventory_creative.png" if name == "inv" then - inv_bg = "crafting_inventory_creative_survival.png" - -- Background images for armor slots (hide if occupied) local armor_slot_imgs = "" local inv = player:get_inventory() if inv:get_stack("armor", 2):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[2.5,1.3;1,1;mcl_inventory_empty_armor_slot_helmet.png]" + armor_slot_imgs = armor_slot_imgs .. "image[3.5,0.375;1,1;mcl_inventory_empty_armor_slot_helmet.png]" end if inv:get_stack("armor", 3):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[2.5,2.75;1,1;mcl_inventory_empty_armor_slot_chestplate.png]" + armor_slot_imgs = armor_slot_imgs .. "image[3.5,2.125;1,1;mcl_inventory_empty_armor_slot_chestplate.png]" end if inv:get_stack("armor", 4):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[5.5,1.3;1,1;mcl_inventory_empty_armor_slot_leggings.png]" + armor_slot_imgs = armor_slot_imgs .. "image[7.25,0.375;1,1;mcl_inventory_empty_armor_slot_leggings.png]" end if inv:get_stack("armor", 5):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[5.5,2.75;1,1;mcl_inventory_empty_armor_slot_boots.png]" + armor_slot_imgs = armor_slot_imgs .. "image[7.25,2.125;1,1;mcl_inventory_empty_armor_slot_boots.png]" end if inv:get_stack("offhand", 1):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[1.5,2.025;1,1;mcl_inventory_empty_armor_slot_shield.png]" + armor_slot_imgs = armor_slot_imgs .. "image[2.25,1.25;1,1;mcl_inventory_empty_armor_slot_shield.png]" end local stack_size = get_stack_size(player) -- Survival inventory slots - main_list = "list[current_player;main;0,3.75;9,3;9]" .. - mcl_formspec.get_itemslot_bg(0, 3.75, 9, 3) .. - + main_list = table.concat({ + mcl_formspec.get_itemslot_bg_v4(0.375, 3.375, 9, 3), + "list[current_player;main;0.375,3.375;9,3;9]", + -- Armor - "list[current_player;armor;2.5,1.3;1,1;1]" .. - "list[current_player;armor;2.5,2.75;1,1;2]" .. - "list[current_player;armor;5.5,1.3;1,1;3]" .. - "list[current_player;armor;5.5,2.75;1,1;4]" .. - mcl_formspec.get_itemslot_bg(2.5, 1.3, 1, 1) .. - mcl_formspec.get_itemslot_bg(2.5, 2.75, 1, 1) .. - mcl_formspec.get_itemslot_bg(5.5, 1.3, 1, 1) .. - mcl_formspec.get_itemslot_bg(5.5, 2.75, 1, 1) .. - "list[current_player;offhand;1.5,2.025;1,1]" .. - mcl_formspec.get_itemslot_bg(1.5, 2.025, 1, 1) .. - armor_slot_imgs .. - + mcl_formspec.get_itemslot_bg_v4(3.5, 0.375, 1, 1), + mcl_formspec.get_itemslot_bg_v4(3.5, 2.125, 1, 1), + mcl_formspec.get_itemslot_bg_v4(7.25, 0.375, 1, 1), + mcl_formspec.get_itemslot_bg_v4(7.25, 2.125, 1, 1), + "list[current_player;armor;3.5,0.375;1,1;1]", + "list[current_player;armor;3.5,2.125;1,1;2]", + "list[current_player;armor;7.25,0.375;1,1;3]", + "list[current_player;armor;7.25,2.125;1,1;4]", + + -- Offhand + mcl_formspec.get_itemslot_bg_v4(2.25, 1.25, 1, 1), + "list[current_player;offhand;2.25,1.25;1,1]", + + armor_slot_imgs, + -- Player preview - mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "") .. - + "image[4.75,0.33;2.25,2.83;mcl_inventory_background9.png;2]", + mcl_player.get_player_formspec_model(player, 4.75, 0.45, 2.25, 2.75, ""), + -- Crafting guide button - "image_button[9,1;1,1;craftguide_book.png;__mcl_craftguide;]" .. - "tooltip[__mcl_craftguide;"..F(S("Recipe book")) .. "]" .. - + "image_button[11.575,0.825;1.1,1.1;craftguide_book.png;__mcl_craftguide;]", + "tooltip[__mcl_craftguide;" .. F(S("Recipe book")) .. "]", + -- Help button - "image_button[9,2;1,1;doc_button_icon_lores.png;__mcl_doc;]" .. - "tooltip[__mcl_doc;" .. F(S("Help")) .. "]" .. - - -- Achievements button - "image_button[9,3;1,1;mcl_achievements_button.png;__mcl_achievements;]" .. - --"style_type[image_button;border=;bgimg=;bgimg_pressed=]" .. - "tooltip[__mcl_achievements;"..F(S("Advancements")) .. "]" .. - + "image_button[11.575,2.075;1.1,1.1;doc_button_icon_lores.png;__mcl_doc;]", + "tooltip[__mcl_doc;" .. F(S("Help")) .. "]", + + -- Advancements button + "image_button[11.575,3.325;1.1,1.1;mcl_achievements_button.png;__mcl_achievements;]", + --"style_type[image_button;border=;bgimg=;bgimg_pressed=]", + "tooltip[__mcl_achievements;" .. F(S("Advancements")) .. "]", + -- Switch stack size button - "image_button[9,4;1,1;default_apple.png;__switch_stack;]" .. - "label[9.4,4.4;" .. F(C("#FFFFFF", stack_size ~= 1 and stack_size or "")) .. "]" .. - "tooltip[__switch_stack;" .. F(S("Switch stack size")) .. "]" - - -- Skins button - if minetest.global_exists("mcl_skins") then - main_list = main_list .. - "image_button[9,5;1,1;mcl_skins_button.png;__mcl_skins;]" .. - "tooltip[__mcl_skins;"..F(S("Select player skin")) .. "]" - end + "image_button[11.575,4.575;1.1,1.1;default_apple.png;__switch_stack;]", + "label[12.275,5.35;" .. F(C("#FFFFFF", tostring(stack_size ~= 1 and stack_size or ""))) .. "]", + "tooltip[__switch_stack;" .. F(S("Switch stack size")) .. "]", + + -- Skins button + "image_button[11.575,5.825;1.1,1.1;mcl_skins_button.png;__mcl_skins;]", + "tooltip[__mcl_skins;" .. F(S("Select player skin")) .. "]", + }) -- For shortcuts listrings = listrings .. - "listring[detached:"..playername.."_armor;armor]".. + "listring[detached:" .. playername .. "_armor;armor]" .. "listring[current_player;main]" else + + --local nb_lines = math.ceil(inv_size / 9) -- Creative inventory slots - main_list = "list[detached:creative_"..playername..";main;0,1.75;9,5;"..tostring(start_i).."]".. - mcl_formspec.get_itemslot_bg(0,1.75,9,5).. - -- Page buttons - "label[9.0,5.5;"..F(S("@1/@2", pagenum, pagemax)).."]".. - "image_button[9.0,6.0;0.7,0.7;crafting_creative_prev.png;creative_prev;]".. - "image_button[9.5,6.0;0.7,0.7;crafting_creative_next.png;creative_next;]" + main_list = table.concat({ + mcl_formspec.get_itemslot_bg_v4(0.375, 0.875, 9, 5), + + -- Basic code to replace buttons by scrollbar + -- Require Minetest 5.8 + -- + --"scroll_container[0.375,0.875;11.575,6;scroll;vertical;1.25]", + --"list[detached:creative_" .. playername .. ";main;0,0;9," .. nb_lines .. ";]", + --"scroll_container_end[]", + --"scrollbaroptions[min=0;max=" .. math.max(nb_lines - 5, 0) .. ";smallstep=1;largesteps=1;arrows=hide]", + --"scrollbar[11.75,0.825;0.75,6.1;vertical;scroll;0]", + + "list[detached:creative_" .. playername .. ";main;0.375,0.875;9,5;" .. tostring(start_i) .. "]", + + -- Page buttons + "label[11.65,4.33;" .. F(S("@1 / @2", pagenum, pagemax)) .. "]", + "image_button[11.575,4.58;1.1,1.1;crafting_creative_prev.png^[transformR270;creative_prev;]", + "image_button[11.575,5.83;1.1,1.1;crafting_creative_next.png^[transformR270;creative_next;]", + }) end - local tab_icon = { - blocks = "mcl_core:brick_block", - deco = "mcl_flowers:peony", - redstone = "mesecons:redstone", - rail = "mcl_minecarts:golden_rail", - misc = "mcl_buckets:bucket_lava", - nix = "mcl_compass:compass", - food = "mcl_core:apple", - tools = "mcl_core:axe_iron", - combat = "mcl_core:sword_gold", - mobs = "mobs_mc:cow", - brew = "mcl_potions:dragon_breath", - matr = "mcl_core:stick", - inv = "mcl_chests:chest", - } + ---@param current_tab string + ---@param this_tab string + ---@return string local function tab(current_tab, this_tab) local bg_img if current_tab == this_tab then - bg_img = "crafting_creative_active"..hoch[this_tab]..".png" + bg_img = "crafting_creative_active" .. button_bg_postfix[this_tab] .. ".png" else - bg_img = "crafting_creative_inactive"..hoch[this_tab]..".png" + bg_img = "crafting_creative_inactive" .. button_bg_postfix[this_tab] .. ".png" end - return - "style["..this_tab..";border=false;bgimg=;bgimg_pressed=]".. - "item_image_button[" .. boffset[this_tab] ..";1,1;"..tab_icon[this_tab]..";"..this_tab..";]".. - "image[" .. offset[this_tab] .. ";1.5,1.44;" .. bg_img .. "]" + return table.concat({ + "style[" .. this_tab .. ";border=false;bgimg=;bgimg_pressed=;noclip=true]", + "image[" .. offset[this_tab] .. ";1.5,1.44;" .. bg_img .. "]", + "item_image_button[" .. boffset[this_tab] .. ";1,1;" .. tab_icon[this_tab] .. ";" .. this_tab .. ";]", + "tooltip[blocks;" .. F(filtername[this_tab]) .. "]" + }) end + local caption = "" if name ~= "inv" and filtername[name] then - caption = "label[0,1.2;"..F(minetest.colorize("#313131", filtername[name])).."]" + caption = "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, filtername[name])) .. "]" end - local formspec = "size[10,9.3]".. - "no_prepend[]".. - mcl_vars.gui_nonbg..mcl_vars.gui_bg_color.. - "background[-0.19,-0.25;10.5,9.87;"..inv_bg.."]".. - "label[-5,-5;"..name.."]".. - tab(name, "blocks") .. - "tooltip[blocks;"..F(filtername["blocks"]).."]".. - tab(name, "deco") .. - "tooltip[deco;"..F(filtername["deco"]).."]".. - tab(name, "redstone") .. - "tooltip[redstone;"..F(filtername["redstone"]).."]".. - tab(name, "rail") .. - "tooltip[rail;"..F(filtername["rail"]).."]".. - tab(name, "misc") .. - "tooltip[misc;"..F(filtername["misc"]).."]".. - tab(name, "nix") .. - "tooltip[nix;"..F(filtername["nix"]).."]".. - caption.. - "list[current_player;main;0,7;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7,9,1).. - main_list.. - tab(name, "food") .. - "tooltip[food;"..F(filtername["food"]).."]".. - tab(name, "tools") .. - "tooltip[tools;"..F(filtername["tools"]).."]".. - tab(name, "combat") .. - "tooltip[combat;"..F(filtername["combat"]).."]".. - tab(name, "mobs") .. - "tooltip[mobs;"..F(filtername["mobs"]).."]".. - tab(name, "brew") .. - "tooltip[brew;"..F(filtername["brew"]).."]".. - tab(name, "matr") .. - "tooltip[matr;"..F(filtername["matr"]).."]".. - tab(name, "inv") .. - "tooltip[inv;"..F(filtername["inv"]).."]".. - "list[detached:trash;main;9,7;1,1;]".. - mcl_formspec.get_itemslot_bg(9,7,1,1).. - "image[9,7;1,1;crafting_creative_trash.png]".. - listrings + local formspec = table.concat({ + "formspec_version[6]", + "size[13,8.75]", + + "style_type[image;noclip=true]", + + -- Hotbar + mcl_formspec.get_itemslot_bg_v4(0.375, 7.375, 9, 1), + "list[current_player;main;0.375,7.375;9,1;]", + + -- Trash + mcl_formspec.get_itemslot_bg_v4(11.625, 7.375, 1, 1, nil, "crafting_creative_trash.png"), + "list[detached:trash;main;11.625,7.375;1,1;]", + + main_list, + + caption, + + listrings, + + tab(name, "blocks"), + tab(name, "deco"), + tab(name, "redstone"), + tab(name, "rail"), + tab(name, "misc"), + tab(name, "nix"), + + tab(name, "food"), + tab(name, "tools"), + tab(name, "combat"), + tab(name, "mobs"), + tab(name, "brew"), + tab(name, "matr"), + tab(name, "inv"), + }) if name == "nix" then - formspec = formspec .. "field[5.3,1.34;4,0.75;search;;"..minetest.formspec_escape(filter).."]" - formspec = formspec .. "field_close_on_enter[search;false]" + if filter == nil then + filter = "" + end + + formspec = formspec .. table.concat({ + "field[5.325,0.15;6.1,0.6;search;;" .. minetest.formspec_escape(filter) .. "]", + "field_close_on_enter[search;false]", + "set_focus[search;true]", + }) end - if pagenum then formspec = formspec .. "p"..tostring(pagenum) end + if pagenum then formspec = formspec .. "p" .. tostring(pagenum) end player:set_inventory_formspec(formspec) end @@ -500,50 +616,50 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if fields.blocks then if players[name].page == "blocks" then return end - set_inv_page("blocks",player) + set_inv_page("blocks", player) page = "blocks" elseif fields.deco then if players[name].page == "deco" then return end - set_inv_page("deco",player) + set_inv_page("deco", player) page = "deco" elseif fields.redstone then if players[name].page == "redstone" then return end - set_inv_page("redstone",player) + set_inv_page("redstone", player) page = "redstone" elseif fields.rail then if players[name].page == "rail" then return end - set_inv_page("rail",player) + set_inv_page("rail", player) page = "rail" elseif fields.misc then if players[name].page == "misc" then return end - set_inv_page("misc",player) + set_inv_page("misc", player) page = "misc" elseif fields.nix then - set_inv_page("all",player) + set_inv_page("all", player) page = "nix" elseif fields.food then if players[name].page == "food" then return end - set_inv_page("food",player) + set_inv_page("food", player) page = "food" elseif fields.tools then if players[name].page == "tools" then return end - set_inv_page("tools",player) + set_inv_page("tools", player) page = "tools" elseif fields.combat then if players[name].page == "combat" then return end - set_inv_page("combat",player) + set_inv_page("combat", player) page = "combat" elseif fields.mobs then if players[name].page == "mobs" then return end - set_inv_page("mobs",player) + set_inv_page("mobs", player) page = "mobs" elseif fields.brew then if players[name].page == "brew" then return end - set_inv_page("brew",player) + set_inv_page("brew", player) page = "brew" elseif fields.matr then if players[name].page == "matr" then return end - set_inv_page("matr",player) + set_inv_page("matr", player) page = "matr" elseif fields.inv then if players[name].page == "inv" then return end @@ -552,7 +668,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) set_inv_page("all", player) page = "nix" elseif fields.search and not fields.creative_next and not fields.creative_prev then - set_inv_search(string.lower(fields.search),player) + set_inv_search(string.lower(fields.search), player) page = "nix" elseif fields.__switch_stack then local switch = 1 @@ -570,20 +686,20 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) local start_i = players[name].start_i if fields.creative_prev then - start_i = start_i - 9*5 + start_i = start_i - 9 * 5 elseif fields.creative_next then - start_i = start_i + 9*5 + start_i = start_i + 9 * 5 else -- Reset scroll bar if not scrolled start_i = 0 end if start_i < 0 then - start_i = start_i + 9*5 + start_i = start_i + 9 * 5 end local inv_size if page == "nix" then - local inv = minetest.get_inventory({type="detached", name="creative_"..name}) + local inv = minetest.get_inventory({ type = "detached", name = "creative_" .. name }) inv_size = inv:get_size("main") elseif page and page ~= "inv" then inv_size = #(inventory_lists[page]) @@ -593,7 +709,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) players[name].inv_size = inv_size if start_i >= inv_size then - start_i = start_i - 9*5 + start_i = start_i - 9 * 5 end if start_i < 0 or start_i >= inv_size then start_i = 0 @@ -609,11 +725,34 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mcl_inventory.set_creative_formspec(player) end) - minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) return placer and placer:is_player() and minetest.is_creative_enabled(placer:get_player_name()) end) +if minetest.is_creative_enabled("") then + minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) + -- Place infinite nodes, except for shulker boxes + local group = minetest.get_item_group(itemstack:get_name(), "shulker_box") + return group == 0 or group == nil + end) + + function minetest.handle_node_drops(pos, drops, digger) + if not digger or not digger:is_player() then + for _, item in ipairs(drops) do + minetest.add_item(pos, item) + end + end + local inv = digger:get_inventory() + if inv then + for _, item in ipairs(drops) do + if not inv:contains_item("main", item, true) then + inv:add_item("main", item) + end + end + end + end +end + minetest.register_on_joinplayer(function(player) -- Initialize variables and inventory local name = player:get_player_name() @@ -629,7 +768,8 @@ minetest.register_on_joinplayer(function(player) end) minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) - if minetest.is_creative_enabled(player:get_player_name()) and get_stack_size(player) == 64 and action == "put" and inventory_info.listname == "main" then + if minetest.is_creative_enabled(player:get_player_name()) and get_stack_size(player) == 64 and action == "put" and + inventory_info.listname == "main" then local stack = inventory_info.stack stack:set_count(stack:get_stack_max()) player:get_inventory():set_stack("main", inventory_info.index, stack) diff --git a/mods/HUD/mcl_inventory/init.lua b/mods/HUD/mcl_inventory/init.lua index 4ca0f2a73..cf484101c 100644 --- a/mods/HUD/mcl_inventory/init.lua +++ b/mods/HUD/mcl_inventory/init.lua @@ -1,13 +1,17 @@ -local S = minetest.get_translator(minetest.get_current_modname()) -local F = minetest.formspec_escape - mcl_inventory = {} +dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/creative.lua") +dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/survival.lua") + --local mod_player = minetest.get_modpath("mcl_player") --local mod_craftguide = minetest.get_modpath("mcl_craftguide") --- Returns a single itemstack in the given inventory to the main inventory, or drop it when there's no space left -function return_item(itemstack, dropper, pos, inv) +---Returns a single itemstack in the given inventory to the main inventory, or drop it when there's no space left. +---@param itemstack mt.ItemStack +---@param dropper mt.ObjectRef +---@param pos mt.Vector +---@param inv mt.InvRef +local function return_item(itemstack, dropper, pos, inv) if dropper:is_player() then -- Return to main inventory if inv:room_for_item("main", itemstack) then @@ -15,14 +19,14 @@ function return_item(itemstack, dropper, pos, inv) else -- Drop item on the ground local v = dropper:get_look_dir() - local p = {x=pos.x, y=pos.y+1.2, z=pos.z} - p.x = p.x+(math.random(1,3)*0.2) - p.z = p.z+(math.random(1,3)*0.2) + local p = vector.offset(pos, 0, 1.2, 0) + p.x = p.x + (math.random(1, 3) * 0.2) + p.z = p.z + (math.random(1, 3) * 0.2) local obj = minetest.add_item(p, itemstack) if obj then - v.x = v.x*4 - v.y = v.y*4 + 2 - v.z = v.z*4 + v.x = v.x * 4 + v.y = v.y * 4 + 2 + v.z = v.z * 4 obj:set_velocity(v) obj:get_luaentity()._insta_collect = false end @@ -34,111 +38,53 @@ function return_item(itemstack, dropper, pos, inv) return itemstack end --- Return items in the given inventory list (name) to the main inventory, or drop them if there is no space left -function return_fields(player, name) +---Return items in the given inventory list (name) to the main inventory, or drop them if there is no space left. +---@param player mt.PlayerObjectRef +---@param name string +local function return_fields(player, name) local inv = player:get_inventory() + local list = inv:get_list(name) if not list then return end - for i,stack in ipairs(list) do + for i, stack in ipairs(list) do return_item(stack, player, player:get_pos(), inv) stack:clear() inv:set_stack(name, i, stack) end end -local function set_inventory(player) +---@param player mt.PlayerObjectRef +---@param armor_change_only? boolean +local function set_inventory(player, armor_change_only) if minetest.is_creative_enabled(player:get_player_name()) then - mcl_inventory.set_creative_formspec(player) + if armor_change_only then + -- Stay on survival inventory plage if only the armor has been changed + mcl_inventory.set_creative_formspec(player, 0, 0, nil, nil, "inv") + else + mcl_inventory.set_creative_formspec(player, 0, 1) + end return end - local inv = player:get_inventory() - inv:set_width("craft", 2) - inv:set_size("craft", 4) - local armor_slots = {"helmet", "chestplate", "leggings", "boots"} - local armor_slot_imgs = "" - for a=1,4 do - if inv:get_stack("armor", a+1):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[0,"..(a-1)..";1,1;mcl_inventory_empty_armor_slot_"..armor_slots[a]..".png]" - end - end - - if inv:get_stack("offhand", 1):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[3,2;1,1;mcl_inventory_empty_armor_slot_shield.png]" - end - - local form = "size[9,8.75]" .. - "background[-0.19,-0.25;9.41,9.49;crafting_formspec_bg.png]" .. - mcl_player.get_player_formspec_model(player, 1.0, 0.0, 2.25, 4.5, "") .. - - -- Armor - "list[current_player;armor;0,0;1,1;1]" .. - "list[current_player;armor;0,1;1,1;2]" .. - "list[current_player;armor;0,2;1,1;3]" .. - "list[current_player;armor;0,3;1,1;4]" .. - mcl_formspec.get_itemslot_bg(0,0,1,1) .. - mcl_formspec.get_itemslot_bg(0,1,1,1) .. - mcl_formspec.get_itemslot_bg(0,2,1,1) .. - mcl_formspec.get_itemslot_bg(0,3,1,1) .. - "list[current_player;offhand;3,2;1,1]" .. - mcl_formspec.get_itemslot_bg(3,2,1,1) .. - armor_slot_imgs .. - - -- Craft and inventory - "label[0,4;"..F(minetest.colorize("#313131", S("Inventory"))) .. "]" .. - "list[current_player;main;0,4.5;9,3;9]" .. - "list[current_player;main;0,7.74;9,1;]" .. - "label[4,0.5;"..F(minetest.colorize("#313131", S("Crafting"))) .. "]" .. - "list[current_player;craft;4,1;2,2]" .. - "list[current_player;craftpreview;7,1.5;1,1;]" .. - mcl_formspec.get_itemslot_bg(0, 4.5, 9, 3) .. - mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1) .. - mcl_formspec.get_itemslot_bg(4, 1,2, 2) .. - mcl_formspec.get_itemslot_bg(7, 1.5, 1, 1) .. - - -- Crafting guide button - "image_button[4.5,3;1,1;craftguide_book.png;__mcl_craftguide;]" .. - "tooltip[__mcl_craftguide;"..F(S("Recipe book")) .. "]" .. - - -- Help button - "image_button[8,3;1,1;doc_button_icon_lores.png;__mcl_doc;]" .. - "tooltip[__mcl_doc;" .. F(S("Help")) .. "]" - - -- Skins button - if minetest.global_exists("mcl_skins") then - form = form .. - "image_button[3,3;1,1;mcl_skins_button.png;__mcl_skins;]" .. - "tooltip[__mcl_skins;" .. F(S("Select player skin")) .. "]" - end - - form = form .. - -- Achievements button - "image_button[7,3;1,1;mcl_achievements_button.png;__mcl_achievements;]" .. - "tooltip[__mcl_achievements;" .. F(S("Advancements")) .. "]" .. - - -- For shortcuts - "listring[current_player;main]" .. - "listring[current_player;armor]" .. - "listring[current_player;main]" .. - "listring[current_player;craft]" .. - "listring[current_player;main]" - - player:set_inventory_formspec(form) + player:set_inventory_formspec(mcl_inventory.build_survival_formspec(player)) end -- Drop items in craft grid and reset inventory on closing minetest.register_on_player_receive_fields(function(player, formname, fields) if fields.quit then - return_fields(player,"craft") - return_fields(player,"enchanting_lapis") - return_fields(player,"enchanting_item") + return_fields(player, "craft") + return_fields(player, "enchanting_lapis") + return_fields(player, "enchanting_item") if not minetest.is_creative_enabled(player:get_player_name()) and (formname == "" or formname == "main") then set_inventory(player) end end end) -mcl_inventory.update_inventory_formspec = set_inventory + +function mcl_inventory.update_inventory_formspec(player) + set_inventory(player) +end -- Drop crafting grid items on leaving minetest.register_on_leaveplayer(function(player) @@ -150,6 +96,7 @@ end) minetest.register_on_joinplayer(function(player) --init inventory local inv = player:get_inventory() + inv:set_width("main", 9) inv:set_size("main", 36) inv:set_size("offhand", 1) @@ -174,73 +121,18 @@ minetest.register_on_joinplayer(function(player) return_fields(player, "enchanting_lapis") end) -dofile(minetest.get_modpath(minetest.get_current_modname()).."/creative.lua") +---@param player mt.PlayerObjectRef +function mcl_inventory.update_inventory(player) + local player_gamemode = mcl_gamemode.get_gamemode(player) + if player_gamemode == "creative" then + mcl_inventory.set_creative_formspec(player) + elseif player_gamemode == "survival" then + player:set_inventory_formspec(mcl_inventory.build_survival_formspec(player)) + end +end + +mcl_gamemode.register_on_gamemode_change(function(player, old_gamemode, new_gamemode) + set_inventory(player) +end) mcl_player.register_on_visual_change(mcl_inventory.update_inventory_formspec) - -local mt_is_creative_enabled = minetest.is_creative_enabled - -function minetest.is_creative_enabled(name) - if mt_is_creative_enabled(name) then return true end - if not name then return false end - local p = minetest.get_player_by_name(name) - if p then - return p:get_meta():get_string("gamemode") == "creative" - end - return false -end - -local function in_table(n,h) - for k,v in pairs(h) do - if v == n then return true end - end - return false -end - -local gamemodes = { - "survival", - "creative" -} - -function mcl_inventory.player_set_gamemode(p,g) - local m = p:get_meta() - m:set_string("gamemode",g) - if g == "survival" then - mcl_experience.setup_hud(p) - mcl_experience.update(p) - elseif g == "creative" then - mcl_experience.remove_hud(p) - end - mcl_meshhand.update_player(p) - set_inventory(p) -end - -minetest.register_chatcommand("gamemode",{ - params = S("[] []"), - description = S("Change gamemode (survival/creative) for yourself or player"), - privs = { server = true }, - func = function(n,param) - -- Full input validation ( just for @erlehmann <3 ) - local p - local args = param:split(" ") - if args[2] ~= nil then - p = minetest.get_player_by_name(args[2]) - n = args[2] - else - p = minetest.get_player_by_name(n) - end - if not p then - return false, S("Player not online") - end - if args[1] ~= nil and not in_table(args[1],gamemodes) then - return false, S("Gamemode " .. args[1] .. " does not exist.") - elseif args[1] ~= nil then - mcl_inventory.player_set_gamemode(p,args[1]) - end - - --Result message - show effective game mode - local gm = p:get_meta():get_string("gamemode") - if gm == "" then gm = gamemodes[1] end - return true, S("Gamemode for player ")..n..S(": "..gm) - end -}) diff --git a/mods/HUD/mcl_inventory/mod.conf b/mods/HUD/mcl_inventory/mod.conf index e42213d4f..66f175c3b 100644 --- a/mods/HUD/mcl_inventory/mod.conf +++ b/mods/HUD/mcl_inventory/mod.conf @@ -1,5 +1,5 @@ name = mcl_inventory author = BlockMen description = Adds the player inventory and creative inventory. -depends = mcl_init, mcl_formspec, mcl_enchanting, mcl_player -optional_depends = mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide +depends = mcl_init, mcl_formspec, mcl_enchanting, mcl_gamemode +optional_depends = mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide, mcl_player diff --git a/mods/HUD/mcl_inventory/survival.lua b/mods/HUD/mcl_inventory/survival.lua new file mode 100644 index 000000000..5b5c6032c --- /dev/null +++ b/mods/HUD/mcl_inventory/survival.lua @@ -0,0 +1,224 @@ +---@diagnostic disable need-check-nil + +local table = table +local ipairs = ipairs + +local S = minetest.get_translator("mcl_inventory") +local F = minetest.formspec_escape + +---@type {id: string, description: string, item_icon: string, build: (fun(player: ObjectRef): string), handle: fun(player: ObjectRef, fields: table), access: (fun(player): boolean), show_inventory: boolean}[] +mcl_inventory.registered_survival_inventory_tabs = {} + +---@param def {id: string, description: string, item_icon: string, build: (fun(player: ObjectRef): string), handle: fun(player: ObjectRef, fields: table), access: (fun(player): boolean), show_inventory: boolean} +function mcl_inventory.register_survival_inventory_tab(def) + if #mcl_inventory.registered_survival_inventory_tabs == 7 then + error("Too much tabs registered!") + end + + assert(def.id) + assert(def.description) + assert(def.item_icon) + assert(def.build) + assert(def.handle) + + for _, d in ipairs(mcl_inventory.registered_survival_inventory_tabs) do + assert(d.id ~= def.id, "Another tab exists with the same name!") + end + + if not def.access then + function def.access(player) + return true + end + end + + if def.show_inventory == nil then + def.show_inventory = true + end + + table.insert(mcl_inventory.registered_survival_inventory_tabs, def) +end + +local player_current_tab = {} + +minetest.register_on_joinplayer(function(player, last_login) + player_current_tab[player] = "main" +end) + +minetest.register_on_leaveplayer(function(player, timed_out) + player_current_tab[player] = nil +end) + +---@param player ObjectRef +---@param content string +---@param inventory boolean +---@param tabname string +local function build_page(player, content, inventory, tabname) + local tab_buttons = "style_type[image;noclip=true]" + + if #mcl_inventory.registered_survival_inventory_tabs ~= 1 then + for i, d in ipairs(mcl_inventory.registered_survival_inventory_tabs) do + local btn_name = "tab_" .. d.id + + tab_buttons = tab_buttons .. table.concat({ + "style[" .. btn_name .. ";border=false;bgimg=;bgimg_pressed=;noclip=true]", + "image[" .. + (0.2 + (i - 1) * 1.6) .. + ",-1.34;1.5,1.44;" .. (tabname == d.id and "crafting_creative_active.png" or "crafting_creative_inactive.png") .. + "]", + "item_image_button[" .. (0.44 + (i - 1) * 1.6) .. ",-1.1;1,1;" .. d.item_icon .. ";" .. btn_name .. ";]", + "tooltip[" .. btn_name .. ";" .. F(d.description) .. "]" + }) + end + end + + return table.concat({ + "formspec_version[6]", + "size[11.75,10.9]", + + inventory and table.concat({ + --Main inventory + mcl_formspec.get_itemslot_bg_v4(0.375, 5.575, 9, 3), + "list[current_player;main;0.375,5.575;9,3;9]", + + --Hotbar + mcl_formspec.get_itemslot_bg_v4(0.375, 9.525, 9, 1), + "list[current_player;main;0.375,9.525;9,1;]" + }) or "", + + content, + tab_buttons, + }) +end + +local main_page_static = table.concat({ + --Armor slots + mcl_formspec.get_itemslot_bg_v4(0.375, 0.375, 1, 4), + "list[current_player;armor;0.375,0.375;1,1;1]", + "list[current_player;armor;0.375,1.625;1,1;2]", + "list[current_player;armor;0.375,2.875;1,1;3]", + "list[current_player;armor;0.375,4.125;1,1;4]", + + --Player model background + "image[1.57,0.343;3.62,4.85;mcl_inventory_background9.png;2]", + + --Offhand + mcl_formspec.get_itemslot_bg_v4(5.375, 4.125, 1, 1), + "list[current_player;offhand;5.375,4.125;1,1]", + + --Craft grid + "label[6.61,0.5;" .. F(minetest.colorize(mcl_formspec.label_color, S("Crafting"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(6.625, 0.875, 2, 2), + "list[current_player;craft;6.625,0.875;2,2]", + + "image[9.125,1.5;1,1;crafting_formspec_arrow.png]", + + mcl_formspec.get_itemslot_bg_v4(10.375, 1.5, 1, 1), + "list[current_player;craftpreview;10.375,1.5;1,1;]", + + --Crafting guide button + "image_button[6.575,4.075;1.1,1.1;craftguide_book.png;__mcl_craftguide;]", + "tooltip[__mcl_craftguide;" .. F(S("Recipe book")) .. "]", + + --Help button + "image_button[7.825,4.075;1.1,1.1;doc_button_icon_lores.png;__mcl_doc;]", + "tooltip[__mcl_doc;" .. F(S("Help")) .. "]", + + --Skins button + "image_button[9.075,4.075;1.1,1.1;mcl_skins_button.png;__mcl_skins;]", + "tooltip[__mcl_skins;" .. F(S("Select player skin")) .. "]", + + --Achievements button + "image_button[10.325,4.075;1.1,1.1;mcl_achievements_button.png;__mcl_achievements;]", + "tooltip[__mcl_achievements;" .. F(S("Achievements")) .. "]", + + --Listring + "listring[current_player;main]", + "listring[current_player;armor]", + "listring[current_player;main]", + "listring[current_player;craft]", + "listring[current_player;main]", +}) + +mcl_inventory.register_survival_inventory_tab({ + id = "main", + description = "Main Inventory", + item_icon = "mcl_crafting_table:crafting_table", + show_inventory = true, + build = function(player) + local inv = player:get_inventory() + + local armor_slots = { "helmet", "chestplate", "leggings", "boots" } + local armor_slot_imgs = "" + + for a = 1, 4 do + if inv:get_stack("armor", a + 1):is_empty() then + armor_slot_imgs = armor_slot_imgs .. + "image[0.375," .. (0.375 + (a - 1) * 1.25) .. ";1,1;mcl_inventory_empty_armor_slot_" .. armor_slots[a] .. ".png]" + end + end + + if inv:get_stack("offhand", 1):is_empty() then + armor_slot_imgs = armor_slot_imgs .. "image[5.375,4.125;1,1;mcl_inventory_empty_armor_slot_shield.png]" + end + return main_page_static .. armor_slot_imgs .. mcl_player.get_player_formspec_model(player, 1.57, 0.4, 3.62, 4.85, "") + end, + handle = function() end, +}) + +--[[ +mcl_inventory.register_survival_inventory_tab({ + id = "test", + description = "Test", + item_icon = "mcl_core:stone", + show_inventory = true, + build = function(player) + return "label[1,1;Hello hello]button[2,2;2,2;Hello;hey]" + end, + handle = function(player, fields) + print(dump(fields)) + end, +})]] + +---@param player ObjectRef +function mcl_inventory.build_survival_formspec(player) + local inv = player:get_inventory() + + inv:set_width("craft", 2) + inv:set_size("craft", 4) + + local tab = player_current_tab[player] + + local tab_def = nil + + for _, d in ipairs(mcl_inventory.registered_survival_inventory_tabs) do + if tab == d.id then + tab_def = d + break + end + end + + local form = build_page(player, tab_def.build(player), tab_def.show_inventory, tab) + + return form +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname == "" and #mcl_inventory.registered_survival_inventory_tabs ~= 1 and + mcl_gamemode.get_gamemode(player) == "survival" then + for _, d in ipairs(mcl_inventory.registered_survival_inventory_tabs) do + if fields["tab_" .. d.id] and d.access(player) then + player_current_tab[player] = d.id + mcl_inventory.update_inventory(player) + return + end + end + + for _, d in ipairs(mcl_inventory.registered_survival_inventory_tabs) do + if player_current_tab[player] == d.id and d.access(player) then + d.handle(player, fields) + return + end + end + end +end) diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index 17d9385a2..ae419a512 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua @@ -8,23 +8,36 @@ All node definitions share a lot of code, so this is the reason why there are so many weird tables below. ]] local S = minetest.get_translator(minetest.get_current_modname()) +local C = minetest.colorize +local F = minetest.formspec_escape --- For after_place_node +local dispenser_formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + + "label[4.125,0.375;" .. F(C(mcl_formspec.label_color, S("Dispenser"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(4.125, 0.75, 3, 3), + "list[context;main;4.125,0.75;3,3;]", + + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + + "listring[context;main]", + "listring[current_player;main]", +}) + +---For after_place_node +---@param pos Vector local function setup_dispenser(pos) -- Set formspec and inventory - local form = "size[9,8.75]".. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[3,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Dispenser"))).."]".. - "list[context;main;3,0.5;3,3;]".. - mcl_formspec.get_itemslot_bg(3,0.5,3,3).. - "listring[context;main]".. - "listring[current_player;main]" local meta = minetest.get_meta(pos) - meta:set_string("formspec", form) + meta:set_string("formspec", dispenser_formspec) local inv = meta:get_inventory() inv:set_size("main", 9) end @@ -38,9 +51,9 @@ local function orientate_dispenser(pos, placer) local node = minetest.get_node(pos) if pitch > 55 then - minetest.swap_node(pos, {name="mcl_dispensers:dispenser_up", param2 = node.param2}) + minetest.swap_node(pos, { name = "mcl_dispensers:dispenser_up", param2 = node.param2 }) elseif pitch < -55 then - minetest.swap_node(pos, {name="mcl_dispensers:dispenser_down", param2 = node.param2}) + minetest.swap_node(pos, { name = "mcl_dispensers:dispenser_down", param2 = node.param2 }) end end @@ -85,11 +98,10 @@ local dispenserdef = { local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() - for i=1, inv:get_size("main") do + for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} - minetest.add_item(p, stack) + minetest.add_item(vector.offset(pos, math.random(0, 10) / 10 - 0.5, 0, math.random(0, 10) / 10 - 0.5), stack) end end meta:from_table(meta2) @@ -107,19 +119,19 @@ local dispenserdef = { dropdir = vector.multiply(minetest.facedir_to_dir(node.param2), -1) droppos = vector.add(pos, dropdir) elseif node.name == "mcl_dispensers:dispenser_up" then - dropdir = {x=0, y=1, z=0} - droppos = {x=pos.x, y=pos.y+1, z=pos.z} + dropdir = vector.new(0, 1, 0) + droppos = vector.offset(pos, 0, 1, 0) elseif node.name == "mcl_dispensers:dispenser_down" then - dropdir = {x=0, y=-1, z=0} - droppos = {x=pos.x, y=pos.y-1, z=pos.z} + dropdir = vector.new(0, -1, 0) + droppos = vector.offset(pos, 0, -1, 0) end local dropnode = minetest.get_node(droppos) local dropnodedef = minetest.registered_nodes[dropnode.name] local stacks = {} - for i=1,inv:get_size("main") do + for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) if not stack:is_empty() then - table.insert(stacks, {stack = stack, stackpos = i}) + table.insert(stacks, { stack = stack, stackpos = i }) end end if #stacks >= 1 then @@ -143,9 +155,10 @@ local dispenserdef = { -- Armor, mob heads and pumpkins if igroups.armor then - local droppos_below = {x = droppos.x, y = droppos.y - 1, z = droppos.z} + local droppos_below = vector.offset(droppos, 0, -1, 0) - for _, objs in ipairs({minetest.get_objects_inside_radius(droppos, 1), minetest.get_objects_inside_radius(droppos_below, 1)}) do + for _, objs in ipairs({ minetest.get_objects_inside_radius(droppos, 1), + minetest.get_objects_inside_radius(droppos_below, 1) }) do for _, obj in ipairs(objs) do stack = mcl_armor.equip(stack, obj) if stack:is_empty() then @@ -157,11 +170,11 @@ local dispenserdef = { end end - -- Place head or pumpkin as node, if equipping it as armor has failed + -- Place head or pumpkin as node, if equipping it as armor has failed if not stack:is_empty() then if igroups.head or iname == "mcl_farming:pumpkin_face" then if dropnodedef.buildable_to then - minetest.set_node(droppos, {name = iname, param2 = node.param2}) + minetest.set_node(droppos, { name = iname, param2 = node.param2 }) stack:take_item() end end @@ -169,7 +182,7 @@ local dispenserdef = { inv:set_stack("main", stack_id, stack) - -- Use shears on sheeps + -- Use shears on sheeps elseif igroups.shears then for _, obj in pairs(minetest.get_objects_inside_radius(droppos, 1)) do local entity = obj:get_luaentity() @@ -220,7 +233,7 @@ local dispenserdef = { end end - -- Spawn Egg + -- Spawn Egg elseif igroups.spawn_egg then -- Spawn mob if not dropnodedef.walkable then @@ -231,7 +244,7 @@ local dispenserdef = { inv:set_stack("main", stack_id, stack) end - -- Generalized dispension + -- Generalized dispension elseif (not dropnodedef.walkable or stackdef._dispense_into_walkable) then --[[ _on_dispense(stack, pos, droppos, dropnode, dropdir) * stack: Itemstack which is dispense @@ -263,7 +276,7 @@ local dispenserdef = { local item_entity = minetest.add_item(droppos, dropitem) local drop_vel = vector.subtract(droppos, pos) local speed = 3 - item_entity:set_velocity(vector.multiply(drop_vel,speed)) + item_entity:set_velocity(vector.multiply(drop_vel, speed)) end else stack:take_item() @@ -280,7 +293,7 @@ local dispenserdef = { local item_entity = minetest.add_item(droppos, dropitem) local drop_vel = vector.subtract(droppos, pos) local speed = 3 - item_entity:set_velocity(vector.multiply(drop_vel,speed)) + item_entity:set_velocity(vector.multiply(drop_vel, speed)) stack:take_item() inv:set_stack("main", stack_id, stack) end @@ -299,27 +312,28 @@ local dispenserdef = { local horizontal_def = table.copy(dispenserdef) horizontal_def.description = S("Dispenser") -horizontal_def._tt_help = S("9 inventory slots").."\n"..S("Launches item when powered by redstone power") +horizontal_def._tt_help = S("9 inventory slots") .. "\n" .. S("Launches item when powered by redstone power") horizontal_def._doc_items_longdesc = S("A dispenser is a block which acts as a redstone component which, when powered with redstone power, dispenses an item. It has a container with 9 inventory slots.") -horizontal_def._doc_items_usagehelp = S("Place the dispenser in one of 6 possible directions. The “hole” is where items will fly out of the dispenser. Use the dispenser to access its inventory. Insert the items you wish to dispense. Supply the dispenser with redstone energy once to dispense a random item.").."\n\n".. +horizontal_def._doc_items_usagehelp = S("Place the dispenser in one of 6 possible directions. The “hole” is where items will fly out of the dispenser. Use the dispenser to access its inventory. Insert the items you wish to dispense. Supply the dispenser with redstone energy once to dispense a random item.") + .. "\n\n" .. -S("The dispenser will do different things, depending on the dispensed item:").."\n\n".. + S("The dispenser will do different things, depending on the dispensed item:") .. "\n\n" .. -S("• Arrows: Are launched").."\n".. -S("• Eggs and snowballs: Are thrown").."\n".. -S("• Fire charges: Are fired in a straight line").."\n".. -S("• Armor: Will be equipped to players and armor stands").."\n".. -S("• Boats: Are placed on water or are dropped").."\n".. -S("• Minecart: Are placed on rails or are dropped").."\n".. -S("• Bone meal: Is applied on the block it is facing").."\n".. -S("• Empty buckets: Are used to collect a liquid source").."\n".. -S("• Filled buckets: Are used to place a liquid source").."\n".. -S("• Heads, pumpkins: Equipped to players and armor stands, or placed as a block").."\n".. -S("• Shulker boxes: Are placed as a block").."\n".. -S("• TNT: Is placed and ignited").."\n".. -S("• Flint and steel: Is used to ignite a fire in air and to ignite TNT").."\n".. -S("• Spawn eggs: Will summon the mob they contain").."\n".. -S("• Other items: Are simply dropped") + S("• Arrows: Are launched") .. "\n" .. + S("• Eggs and snowballs: Are thrown") .. "\n" .. + S("• Fire charges: Are fired in a straight line") .. "\n" .. + S("• Armor: Will be equipped to players and armor stands") .. "\n" .. + S("• Boats: Are placed on water or are dropped") .. "\n" .. + S("• Minecart: Are placed on rails or are dropped") .. "\n" .. + S("• Bone meal: Is applied on the block it is facing") .. "\n" .. + S("• Empty buckets: Are used to collect a liquid source") .. "\n" .. + S("• Filled buckets: Are used to place a liquid source") .. "\n" .. + S("• Heads, pumpkins: Equipped to players and armor stands, or placed as a block") .. "\n" .. + S("• Shulker boxes: Are placed as a block") .. "\n" .. + S("• TNT: Is placed and ignited") .. "\n" .. + S("• Flint and steel: Is used to ignite a fire in air and to ignite TNT") .. "\n" .. + S("• Spawn eggs: Will summon the mob they contain") .. "\n" .. + S("• Other items: Are simply dropped") function horizontal_def.after_place_node(pos, placer, itemstack, pointed_thing) setup_dispenser(pos) @@ -332,7 +346,7 @@ horizontal_def.tiles = { "default_furnace_side.png", "mcl_dispensers_dispenser_front_horizontal.png" } horizontal_def.paramtype2 = "facedir" -horizontal_def.groups = {pickaxey=1, container=2, material_stone=1} +horizontal_def.groups = { pickaxey = 1, container = 2, material_stone = 1 } minetest.register_node("mcl_dispensers:dispenser", horizontal_def) @@ -345,7 +359,7 @@ down_def.tiles = { "default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png" } -down_def.groups = {pickaxey=1, container=2,not_in_creative_inventory=1, material_stone=1} +down_def.groups = { pickaxey = 1, container = 2, not_in_creative_inventory = 1, material_stone = 1 } down_def._doc_items_create_entry = false down_def.drop = "mcl_dispensers:dispenser" minetest.register_node("mcl_dispensers:dispenser_down", down_def) @@ -365,9 +379,9 @@ minetest.register_node("mcl_dispensers:dispenser_up", up_def) minetest.register_craft({ output = "mcl_dispensers:dispenser", recipe = { - {"mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble",}, - {"mcl_core:cobble", "mcl_bows:bow", "mcl_core:cobble",}, - {"mcl_core:cobble", "mesecons:redstone", "mcl_core:cobble",}, + { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble", }, + { "mcl_core:cobble", "mcl_bows:bow", "mcl_core:cobble", }, + { "mcl_core:cobble", "mesecons:redstone", "mcl_core:cobble", }, } }) @@ -384,6 +398,6 @@ minetest.register_lbm({ nodenames = { "mcl_dispensers:dispenser", "mcl_dispensers:dispenser_down", "mcl_dispensers:dispenser_up" }, action = function(pos, node) setup_dispenser(pos) - minetest.log("action", "[mcl_dispenser] Node formspec updated at "..minetest.pos_to_string(pos)) + minetest.log("action", "[mcl_dispenser] Node formspec updated at " .. minetest.pos_to_string(pos)) end, }) diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua index 5f8f94d84..09e221a4d 100644 --- a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua @@ -9,23 +9,36 @@ are so many weird tables below. ]] local S = minetest.get_translator(minetest.get_current_modname()) +local C = minetest.colorize +local F = minetest.formspec_escape --- For after_place_node +local dropper_formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + + "label[4.125,0.375;" .. F(C(mcl_formspec.label_color, S("Dropper"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(4.125, 0.75, 3, 3), + "list[context;main;4.125,0.75;3,3;]", + + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + + "listring[context;main]", + "listring[current_player;main]", +}) + +---For after_place_node +---@param pos Vector local function setup_dropper(pos) -- Set formspec and inventory - local form = "size[9,8.75]".. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[3,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Dropper"))).."]".. - "list[context;main;3,0.5;3,3;]".. - mcl_formspec.get_itemslot_bg(3,0.5,3,3).. - "listring[context;main]".. - "listring[current_player;main]" local meta = minetest.get_meta(pos) - meta:set_string("formspec", form) + meta:set_string("formspec", dropper_formspec) local inv = meta:get_inventory() inv:set_size("main", 9) end @@ -38,9 +51,9 @@ local function orientate_dropper(pos, placer) local pitch = placer:get_look_vertical() * (180 / math.pi) if pitch > 55 then - minetest.swap_node(pos, {name="mcl_droppers:dropper_up"}) + minetest.swap_node(pos, { name = "mcl_droppers:dropper_up" }) elseif pitch < -55 then - minetest.swap_node(pos, {name="mcl_droppers:dropper_down"}) + minetest.swap_node(pos, { name = "mcl_droppers:dropper_down" }) end end @@ -58,11 +71,10 @@ local dropperdef = { local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() - for i=1, inv:get_size("main") do + for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} - minetest.add_item(p, stack) + minetest.add_item(vector.offset(pos, math.random(0, 10) / 10 - 0.5, 0, math.random(0, 10) / 10 - 0.5), stack) end end meta:from_table(meta2) @@ -96,7 +108,7 @@ local dropperdef = { end, _mcl_blast_resistance = 3.5, _mcl_hardness = 3.5, - mesecons = {effector = { + mesecons = { effector = { -- Drop random item when triggered action_on = function(pos, node) if not pos then return end @@ -104,11 +116,11 @@ local dropperdef = { local inv = meta:get_inventory() local droppos if node.name == "mcl_droppers:dropper" then - droppos = vector.subtract(pos, minetest.facedir_to_dir(node.param2)) + droppos = vector.subtract(pos, minetest.facedir_to_dir(node.param2)) elseif node.name == "mcl_droppers:dropper_up" then - droppos = {x=pos.x, y=pos.y+1, z=pos.z} + droppos = vector.offset(pos, 0, 1, 0) elseif node.name == "mcl_droppers:dropper_down" then - droppos = {x=pos.x, y=pos.y-1, z=pos.z} + droppos = vector.offset(pos, 0, -1, 0) end local dropnode = minetest.get_node(droppos) -- Do not drop into solid nodes, unless they are containers @@ -117,10 +129,10 @@ local dropperdef = { return end local stacks = {} - for i=1,inv:get_size("main") do + for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) if not stack:is_empty() then - table.insert(stacks, {stack = stack, stackpos = i}) + table.insert(stacks, { stack = stack, stackpos = i }) end end if #stacks >= 1 then @@ -136,22 +148,22 @@ local dropperdef = { if not dropped and not dropnodedef.groups.container then -- Drop item normally local pos_variation = 100 - droppos = { - x = droppos.x + math.random(-pos_variation, pos_variation) / 1000, - y = droppos.y + math.random(-pos_variation, pos_variation) / 1000, - z = droppos.z + math.random(-pos_variation, pos_variation) / 1000, - } + droppos = vector.offset(droppos, + math.random(-pos_variation, pos_variation) / 1000, + math.random(-pos_variation, pos_variation) / 1000, + math.random(-pos_variation, pos_variation) / 1000 + ) local item_entity = minetest.add_item(droppos, dropitem) local drop_vel = vector.subtract(droppos, pos) local speed = 3 - item_entity:set_velocity(vector.multiply(drop_vel,speed)) + item_entity:set_velocity(vector.multiply(drop_vel, speed)) stack:take_item() inv:set_stack("main", stack_id, stack) end end end, rules = mesecon.rules.alldirs, - }}, + } }, on_rotate = on_rotate, } @@ -159,20 +171,21 @@ local dropperdef = { local horizontal_def = table.copy(dropperdef) horizontal_def.description = S("Dropper") -horizontal_def._tt_help = S("9 inventory slots").."\n"..S("Drops item when powered by redstone power") +horizontal_def._tt_help = S("9 inventory slots") .. "\n" .. S("Drops item when powered by redstone power") horizontal_def._doc_items_longdesc = S("A dropper is a redstone component and a container with 9 inventory slots which, when supplied with redstone power, drops an item or puts it into a container in front of it.") horizontal_def._doc_items_usagehelp = S("Droppers can be placed in 6 possible directions, items will be dropped out of the hole. Use the dropper to access its inventory. Supply it with redstone energy once to make the dropper drop or transfer a random item.") function horizontal_def.after_place_node(pos, placer, itemstack, pointed_thing) setup_dropper(pos) orientate_dropper(pos, placer) end + horizontal_def.tiles = { "default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png", "mcl_droppers_dropper_front_horizontal.png" } horizontal_def.paramtype2 = "facedir" -horizontal_def.groups = {pickaxey=1, container=2, material_stone=1} +horizontal_def.groups = { pickaxey = 1, container = 2, material_stone = 1 } minetest.register_node("mcl_droppers:dropper", horizontal_def) @@ -185,7 +198,7 @@ down_def.tiles = { "default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png" } -down_def.groups = {pickaxey=1, container=2,not_in_creative_inventory=1, material_stone=1} +down_def.groups = { pickaxey = 1, container = 2, not_in_creative_inventory = 1, material_stone = 1 } down_def._doc_items_create_entry = false down_def.drop = "mcl_droppers:dropper" minetest.register_node("mcl_droppers:dropper_down", down_def) @@ -207,9 +220,9 @@ minetest.register_node("mcl_droppers:dropper_up", up_def) minetest.register_craft({ output = "mcl_droppers:dropper", recipe = { - {"mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble",}, - {"mcl_core:cobble", "", "mcl_core:cobble",}, - {"mcl_core:cobble", "mesecons:redstone", "mcl_core:cobble",}, + { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble", }, + { "mcl_core:cobble", "", "mcl_core:cobble", }, + { "mcl_core:cobble", "mesecons:redstone", "mcl_core:cobble", }, } }) @@ -226,6 +239,6 @@ minetest.register_lbm({ nodenames = { "mcl_droppers:dropper", "mcl_droppers:dropper_down", "mcl_droppers:dropper_up" }, action = function(pos, node) setup_dropper(pos) - minetest.log("action", "[mcl_droppers] Node formspec updated at "..minetest.pos_to_string(pos)) + minetest.log("action", "[mcl_droppers] Node formspec updated at " .. minetest.pos_to_string(pos)) end, }) diff --git a/mods/ITEMS/mcl_anvils/init.lua b/mods/ITEMS/mcl_anvils/init.lua index a56299cd9..b41411f15 100644 --- a/mods/ITEMS/mcl_anvils/init.lua +++ b/mods/ITEMS/mcl_anvils/init.lua @@ -1,4 +1,6 @@ local S = minetest.get_translator(minetest.get_current_modname()) +local F = minetest.formspec_escape +local C = minetest.colorize local MAX_NAME_LENGTH = 35 local MAX_WEAR = 65535 @@ -10,41 +12,65 @@ local MATERIAL_TOOL_REPAIR_BOOST = { MAX_WEAR, -- 100% } +---@param set_name? string local function get_anvil_formspec(set_name) if not set_name then set_name = "" end - return "size[9,8.75]".. - "background[-0.19,-0.25;9.41,9.49;mcl_anvils_inventory.png]".. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "list[context;input;1,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(1,2.5,1,1).. - "list[context;input;4,2.5;1,1;1]".. - mcl_formspec.get_itemslot_bg(4,2.5,1,1).. - "list[context;output;8,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(8,2.5,1,1).. - "label[3,0.1;"..minetest.formspec_escape(minetest.colorize("#313131", S("Repair and Name"))).."]".. - "field[3.25,1;4,1;name;;"..minetest.formspec_escape(set_name).."]".. - "field_close_on_enter[name;false]".. - "button[7,0.7;2,1;name_button;"..minetest.formspec_escape(S("Set Name")).."]".. - "listring[context;output]".. - "listring[current_player;main]".. - "listring[context;input]".. - "listring[current_player;main]" + + return table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + + "label[4.125,0.375;" .. F(C(mcl_formspec.label_color, S("Repair and Name"))) .. "]", + + "image[0.875,0.375;1.75,1.75;mcl_anvils_inventory_hammer.png]", + + "field[4.125,0.75;7.25,1;name;;" .. F(set_name) .. "]", + "field_close_on_enter[name;false]", + "set_focus[name;true]", + + mcl_formspec.get_itemslot_bg_v4(1.625, 2.6, 1, 1), + "list[context;input;1.625,2.6;1,1;]", + + "image[3.5,2.6;1,1;mcl_anvils_inventory_cross.png]", + + mcl_formspec.get_itemslot_bg_v4(5.375, 2.6, 1, 1), + "list[context;input;5.375,2.6;1,1;1]", + + "image[6.75,2.6;2,1;mcl_anvils_inventory_arrow.png]", + + mcl_formspec.get_itemslot_bg_v4(9.125, 2.6, 1, 1), + "list[context;output;9.125,2.6;1,1;]", + + -- Player Inventory + + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + + -- Listrings + + "listring[context;output]", + "listring[current_player;main]", + "listring[context;input]", + "listring[current_player;main]", + }) end -- Given a tool and material stack, returns how many items of the material stack -- needs to be used up to repair the tool. +---@param tool ItemStack +---@param material ItemStack +---@return integer local function get_consumed_materials(tool, material) local wear = tool:get_wear() --local health = (MAX_WEAR - wear) local matsize = material:get_count() local materials_used = 0 - for m=1, math.min(4, matsize) do + for m = 1, math.min(4, matsize) do materials_used = materials_used + 1 if (wear - MATERIAL_TOOL_REPAIR_BOOST[m]) <= 0 then break @@ -53,27 +79,20 @@ local function get_consumed_materials(tool, material) return materials_used end -local function contains(table, value) - for _, i in pairs(table) do - if i == value then - return true - end - end - return false -end - -- Given 2 input stacks, tells you which is the tool and which is the material. -- Returns ("tool", input1, input2) if input1 is tool and input2 is material. -- Returns ("material", input2, input1) if input1 is material and input2 is tool. -- Returns nil otherwise. +---@param input1 ItemStack +---@param input2 ItemStack local function distinguish_tool_and_material(input1, input2) local def1 = input1:get_definition() local def2 = input2:get_definition() local r1 = def1._repair_material local r2 = def2._repair_material - if def1.type == "tool" and r1 and type(r1) == "table" and contains(r1, input2) then + if def1.type == "tool" and r1 and type(r1) == "table" and table.indexof(r1, input2) ~= -1 then return "tool", input1, input2 - elseif def2.type == "tool" and r2 and type(r2) == "table" and contains(r2, input1) then + elseif def2.type == "tool" and r2 and type(r2) == "table" and table.indexof(r1, input1) ~= -1 then return "material", input2, input1 elseif def1.type == "tool" and r1 then return "tool", input1, input2 @@ -84,7 +103,8 @@ local function distinguish_tool_and_material(input1, input2) end end --- Helper function to make sure update_anvil_slots NEVER overstacks the output slot +---Helper function to make sure update_anvil_slots NEVER overstacks the output slot +---@param stack ItemStack local function fix_stack_size(stack) if not stack or stack == "" then return "" end local count = stack:get_count() @@ -99,6 +119,7 @@ end -- Update the inventory slots of an anvil node. -- meta: Metadata of anvil node +---@param meta NodeMetaRef local function update_anvil_slots(meta) local inv = meta:get_inventory() local new_name = meta:get_string("set_name") @@ -137,7 +158,7 @@ local function update_anvil_slots(meta) name_item = input1 new_output = name_item - -- Tool + repair item + -- Tool + repair item else -- Any tool can have a repair item. This may be defined in the tool's item definition -- as an itemstring in the field `_repair_material`. Only if this field is set, the @@ -159,7 +180,7 @@ local function update_anvil_slots(meta) has_correct_material = true end else - if contains(repair, material_name) then + if table.indexof(repair, material_name) ~= -1 then has_correct_material = true else for _, r in pairs(repair) do @@ -185,7 +206,7 @@ local function update_anvil_slots(meta) new_output = "" end end - -- Exactly 1 input slot occupied + -- Exactly 1 input slot occupied elseif (not input1:is_empty() and input2:is_empty()) or (input1:is_empty() and not input2:is_empty()) then -- Just rename item if input1:is_empty() then @@ -231,28 +252,32 @@ local function update_anvil_slots(meta) end end --- Drop input items of anvil at pos with metadata meta +---Drop input items of anvil at pos with metadata meta +---@param pos Vector +---@param meta NodeMetaRef local function drop_anvil_items(pos, meta) local inv = meta:get_inventory() - for i=1, inv:get_size("input") do + for i = 1, inv:get_size("input") do local stack = inv:get_stack("input", i) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = vector.offset(pos, math.random(0, 10) / 10 - 0.5, 0, math.random(0, 10) / 10 - 0.5) minetest.add_item(p, stack) end end end +---@param pos Vector +---@param node node local function damage_particles(pos, node) minetest.add_particlespawner({ amount = 30, time = 0.1, - minpos = vector.add(pos, {x=-0.5, y=-0.5, z=-0.5}), - maxpos = vector.add(pos, {x=0.5, y=-0.25, z=0.5}), - minvel = {x=-0.5, y=0.05, z=-0.5}, - maxvel = {x=0.5, y=0.3, z=0.5}, - minacc = {x=0, y=-9.81, z=0}, - maxacc = {x=0, y=-9.81, z=0}, + minpos = vector.offset(pos, -0.5, -0.5, -0.5), + maxpos = vector.offset(pos, 0.5, -0.25, 0.5), + minvel = vector.new(-0.5, 0.05, -0.5), + maxvel = vector.new(0.5, 0.3, 0.5), + minacc = vector.new(0, -9.81, 0), + maxacc = vector.new(0, -9.81, 0), minexptime = 0.1, maxexptime = 0.5, minsize = 0.4, @@ -267,12 +292,12 @@ local function destroy_particles(pos, node) minetest.add_particlespawner({ amount = math.random(20, 30), time = 0.1, - minpos = vector.add(pos, {x=-0.4, y=-0.4, z=-0.4}), - maxpos = vector.add(pos, {x=0.4, y=0.4, z=0.4}), - minvel = {x=-0.5, y=-0.1, z=-0.5}, - maxvel = {x=0.5, y=0.2, z=0.5}, - minacc = {x=0, y=-9.81, z=0}, - maxacc = {x=0, y=-9.81, z=0}, + minpos = vector.offset(pos, -0.4, -0.4, -0.4), + maxpos = vector.offset(pos, 0.4, 0.4, 0.4), + minvel = vector.new(-0.5, -0.1, -0.5), + maxvel = vector.new(0.5, 0.2, 0.5), + minacc = vector.new(0, -9.81, 0), + maxacc = vector.new(0, -9.81, 0), minexptime = 0.2, maxexptime = 0.65, minsize = 0.8, @@ -289,28 +314,29 @@ end local function damage_anvil(pos) local node = minetest.get_node(pos) if node.name == "mcl_anvils:anvil" then - minetest.swap_node(pos, {name="mcl_anvils:anvil_damage_1", param2=node.param2}) + minetest.swap_node(pos, { name = "mcl_anvils:anvil_damage_1", param2 = node.param2 }) damage_particles(pos, node) - minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dig, {pos=pos, max_hear_distance=16}, true) + minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dig, { pos = pos, max_hear_distance = 16 }, true) return false elseif node.name == "mcl_anvils:anvil_damage_1" then - minetest.swap_node(pos, {name="mcl_anvils:anvil_damage_2", param2=node.param2}) + minetest.swap_node(pos, { name = "mcl_anvils:anvil_damage_2", param2 = node.param2 }) damage_particles(pos, node) - minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dig, {pos=pos, max_hear_distance=16}, true) + minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dig, { pos = pos, max_hear_distance = 16 }, true) return false elseif node.name == "mcl_anvils:anvil_damage_2" then -- Destroy anvil local meta = minetest.get_meta(pos) drop_anvil_items(pos, meta) - minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dug, {pos=pos, max_hear_distance=16}, true) + minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dug, { pos = pos, max_hear_distance = 16 }, true) minetest.remove_node(pos) destroy_particles(pos, node) - minetest.check_single_for_falling({x=pos.x, y=pos.y+1, z=pos.z}) + minetest.check_single_for_falling(vector.offset(pos, 0, 1, 0)) return true end end --- Roll a virtual dice and damage anvil at a low chance. +---Roll a virtual dice and damage anvil at a low chance. +---@param pos Vector local function damage_anvil_by_using(pos) local r = math.random(1, 100) -- 12% chance @@ -321,25 +347,30 @@ local function damage_anvil_by_using(pos) end end +---@param pos Vector +---@param distance number local function damage_anvil_by_falling(pos, distance) local r = math.random(1, 100) if distance > 1 then - if r <= (5*distance) then + if r <= (5 * distance) then damage_anvil(pos) end end end +---@type nodebox local anvilbox = { type = "fixed", fixed = { { -8 / 16, -8 / 16, -6 / 16, 8 / 16, 8 / 16, 6 / 16 }, }, } + +---@type node_definition local anvildef = { - groups = {pickaxey=1, falling_node=1, falling_node_damage=1, crush_after_fall=1, deco_block=1, anvil=1}, - tiles = {"mcl_anvils_anvil_top_damaged_0.png^[transformR90", "mcl_anvils_anvil_base.png", "mcl_anvils_anvil_side.png"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + groups = { pickaxey = 1, falling_node = 1, falling_node_damage = 1, crush_after_fall = 1, deco_block = 1, anvil = 1 }, + tiles = { "mcl_anvils_anvil_top_damaged_0.png^[transformR90", "mcl_anvils_anvil_base.png", "mcl_anvils_anvil_side.png" }, + use_texture_alpha = "opaque", _tt_help = S("Repair and rename items"), paramtype = "light", sunlight_propagates = true, @@ -353,7 +384,7 @@ local anvildef = { { -5 / 16, -4 / 16, -4 / 16, 5 / 16, -3 / 16, 4 / 16 }, { -4 / 16, -3 / 16, -2 / 16, 4 / 16, 2 / 16, 2 / 16 }, { -8 / 16, 2 / 16, -5 / 16, 8 / 16, 8 / 16, 5 / 16 }, - } + }, }, selection_box = anvilbox, collision_box = anvilbox, @@ -416,7 +447,7 @@ local anvildef = { local meta = minetest.get_meta(pos) if from_list == "output" and to_list == "input" then local inv = meta:get_inventory() - for i=1, inv:get_size("input") do + for i = 1, inv:get_size("input") do if i ~= to_index then local istack = inv:get_stack("input", i) istack:set_count(math.max(0, istack:get_count() - count)) @@ -504,22 +535,20 @@ local anvildef = { minetest.record_protection_violation(pos, sender_name) return end - if fields.name_button or fields.name then - local set_name - if fields.name == nil then - set_name = "" - else - set_name = fields.name - end + + if fields.name then local meta = minetest.get_meta(pos) + -- Limit name length - set_name = string.sub(set_name, 1, MAX_NAME_LENGTH) + local set_name = string.sub(fields.name, 1, MAX_NAME_LENGTH) + meta:set_string("set_name", set_name) update_anvil_slots(meta) meta:set_string("formspec", get_anvil_formspec(set_name)) end end, } + if minetest.get_modpath("screwdriver") then anvildef.on_rotate = screwdriver.rotate_simple end @@ -527,29 +556,34 @@ end local anvildef0 = table.copy(anvildef) anvildef0.description = S("Anvil") anvildef0._doc_items_longdesc = -S("The anvil allows you to repair tools and armor, and to give names to items. It has a limited durability, however. Don't let it fall on your head, it could be quite painful!") + S("The anvil allows you to repair tools and armor, and to give names to items. It has a limited durability, however. Don't let it fall on your head, it could be quite painful!") anvildef0._doc_items_usagehelp = -S("To use an anvil, rightclick it. An anvil has 2 input slots (on the left) and one output slot.").."\n".. -S("To rename items, put an item stack in one of the item slots while keeping the other input slot empty. Type in a name, hit enter or “Set Name”, then take the renamed item from the output slot.").."\n".. -S("There are two possibilities to repair tools (and armor):").."\n".. -S("• Tool + Tool: Place two tools of the same type in the input slots. The “health” of the repaired tool is the sum of the “health” of both input tools, plus a 12% bonus.").."\n".. -S("• Tool + Material: Some tools can also be repaired by combining them with an item that it's made of. For example, iron pickaxes can be repaired with iron ingots. This repairs the tool by 25%.").."\n".. -S("Armor counts as a tool. It is possible to repair and rename a tool in a single step.").."\n\n".. -S("The anvil has limited durability and 3 damage levels: undamaged, slightly damaged and very damaged. Each time you repair or rename something, there is a 12% chance the anvil gets damaged. Anvils also have a chance of being damaged when they fall by more than 1 block. If a very damaged anvil is damaged again, it is destroyed.") + S("To use an anvil, rightclick it. An anvil has 2 input slots (on the left) and one output slot.") .. "\n" .. + S("To rename items, put an item stack in one of the item slots while keeping the other input slot empty. Type in a name, hit enter or “Set Name”, then take the renamed item from the output slot.") + .. "\n" .. + S("There are two possibilities to repair tools (and armor):") .. "\n" .. + S("• Tool + Tool: Place two tools of the same type in the input slots. The “health” of the repaired tool is the sum of the “health” of both input tools, plus a 12% bonus.") + .. "\n" .. + S("• Tool + Material: Some tools can also be repaired by combining them with an item that it's made of. For example, iron pickaxes can be repaired with iron ingots. This repairs the tool by 25%.") + .. "\n" .. + S("Armor counts as a tool. It is possible to repair and rename a tool in a single step.") .. "\n\n" .. + S("The anvil has limited durability and 3 damage levels: undamaged, slightly damaged and very damaged. Each time you repair or rename something, there is a 12% chance the anvil gets damaged. Anvils also have a chance of being damaged when they fall by more than 1 block. If a very damaged anvil is damaged again, it is destroyed.") local anvildef1 = table.copy(anvildef) anvildef1.description = S("Slightly Damaged Anvil") anvildef1._doc_items_create_entry = false anvildef1.groups.anvil = 2 anvildef1._doc_items_create_entry = false -anvildef1.tiles = {"mcl_anvils_anvil_top_damaged_1.png^[transformR90", "mcl_anvils_anvil_base.png", "mcl_anvils_anvil_side.png"} +anvildef1.tiles = { "mcl_anvils_anvil_top_damaged_1.png^[transformR90", "mcl_anvils_anvil_base.png", + "mcl_anvils_anvil_side.png" } local anvildef2 = table.copy(anvildef) anvildef2.description = S("Very Damaged Anvil") anvildef2._doc_items_create_entry = false anvildef2.groups.anvil = 3 anvildef2._doc_items_create_entry = false -anvildef2.tiles = {"mcl_anvils_anvil_top_damaged_2.png^[transformR90", "mcl_anvils_anvil_base.png", "mcl_anvils_anvil_side.png"} +anvildef2.tiles = { "mcl_anvils_anvil_top_damaged_2.png^[transformR90", "mcl_anvils_anvil_base.png", + "mcl_anvils_anvil_side.png" } minetest.register_node("mcl_anvils:anvil", anvildef0) minetest.register_node("mcl_anvils:anvil_damage_1", anvildef1) @@ -562,7 +596,7 @@ if minetest.get_modpath("mcl_core") then { "mcl_core:ironblock", "mcl_core:ironblock", "mcl_core:ironblock" }, { "", "mcl_core:iron_ingot", "" }, { "mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot" }, - } + }, }) end diff --git a/mods/ITEMS/mcl_barrels/init.lua b/mods/ITEMS/mcl_barrels/init.lua index 714a80f09..e2f46be28 100644 --- a/mods/ITEMS/mcl_barrels/init.lua +++ b/mods/ITEMS/mcl_barrels/init.lua @@ -8,6 +8,7 @@ local open_barrels = {} local drop_content = mcl_util.drop_items_from_meta_container("main") +---@param pos Vector local function on_blast(pos) local node = minetest.get_node(pos) drop_content(pos, node) @@ -45,30 +46,34 @@ local function barrel_open(pos, node, clicker) local playername = clicker:get_player_name() minetest.show_formspec(playername, - "mcl_barrels:barrel_"..pos.x.."_"..pos.y.."_"..pos.z, + "mcl_barrels:barrel_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z, table.concat({ - "size[9,8.75]", - "label[0,0;"..F(C("#313131", name)).."]", - "list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0.5;9,3;]", - mcl_formspec.get_itemslot_bg(0, 0.5, 9, 3), - "label[0,4.0;"..F(C("#313131", S("Inventory"))).."]", - "list[current_player;main;0,4.5;9,3;9]", - mcl_formspec.get_itemslot_bg(0, 4.5, 9, 3), - "list[current_player;main;0,7.74;9,1;]", - mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1), - "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main]", + "formspec_version[4]", + "size[11.75,10.425]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, name)) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3), + "list[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";main;0.375,0.75;9,3;]", + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + "listring[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";main]", "listring[current_player;main]", }) ) - minetest.swap_node(pos, { name = "mcl_barrels:barrel_open", param2 = node.param2 }) + minetest.swap_node(pos, { name = "mcl_barrels:barrel_open", param2 = node.param2 }) open_barrels[playername] = pos - minetest.sound_play({name="mcl_barrels_default_barrel_open", pos=pos, gain=0.5, max_hear_distance=16}, true) + minetest.sound_play({ name = "mcl_barrels_default_barrel_open", pos = pos, gain = 0.5, max_hear_distance = 16 }, true) end +---@param pos Vector local function close_forms(pos) local players = minetest.get_connected_players() - local formname = "mcl_barrels:barrel_"..pos.x.."_"..pos.y.."_"..pos.z + local formname = "mcl_barrels:barrel_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z for p = 1, #players do if vector.distance(players[p]:get_pos(), pos) <= 30 then minetest.close_formspec(players[p]:get_player_name(), formname) @@ -76,15 +81,18 @@ local function close_forms(pos) end end +---@param pos Vector local function update_after_close(pos) local node = minetest.get_node_or_nil(pos) if not node then return end if node.name == "mcl_barrels:barrel_open" then - minetest.swap_node(pos, {name = "mcl_barrels:barrel_closed", param2 = node.param2}) - minetest.sound_play({name="mcl_barrels_default_barrel_close", pos=pos, gain=0.5, max_hear_distance=16}, true) + minetest.swap_node(pos, { name = "mcl_barrels:barrel_closed", param2 = node.param2 }) + minetest.sound_play({ name = "mcl_barrels_default_barrel_close", pos = pos, gain = 0.5, max_hear_distance = 16 }, + true) end end +---@param player ObjectRef local function close_barrel(player) local name = player:get_player_name() local open = open_barrels[name] @@ -102,20 +110,22 @@ minetest.register_node("mcl_barrels:barrel_closed", { _tt_help = S("27 inventory slots"), _doc_items_longdesc = S("Barrels are containers which provide 27 inventory slots."), _doc_items_usagehelp = S("To access its inventory, rightclick it. When broken, the items will drop out."), - tiles = {"mcl_barrels_barrel_top.png^[transformR270", "mcl_barrels_barrel_bottom.png", "mcl_barrels_barrel_side.png"}, + tiles = { "mcl_barrels_barrel_top.png^[transformR270", "mcl_barrels_barrel_bottom.png", "mcl_barrels_barrel_side.png" }, paramtype = "light", paramtype2 = "facedir", on_place = function(itemstack, placer, pointed_thing) - minetest.rotate_and_place(itemstack, placer, pointed_thing, minetest.is_creative_enabled(placer:get_player_name()), {}, false) + minetest.rotate_and_place(itemstack, placer, pointed_thing, + minetest.is_creative_enabled(placer:get_player_name()), {} + , false) return itemstack end, stack_max = 64, sounds = mcl_sounds.node_sound_wood_defaults(), - groups = {handy = 1, axey = 1, container = 2, material_wood = 1, flammable = -1, deco_block = 1}, + groups = { handy = 1, axey = 1, container = 2, material_wood = 1, flammable = -1, deco_block = 1 }, on_construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - inv:set_size("main", 9*3) + inv:set_size("main", 9 * 3) end, after_place_node = function(pos, placer, itemstack, pointed_thing) minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) @@ -124,16 +134,16 @@ minetest.register_node("mcl_barrels:barrel_closed", { allow_metadata_inventory_take = protection_check_put_take, allow_metadata_inventory_put = protection_check_put_take, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in barrel at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in barrel at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to barrel at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to barrel at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from barrel at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from barrel at " .. minetest.pos_to_string(pos)) end, after_dig_node = drop_content, on_blast = on_blast, @@ -149,27 +159,35 @@ minetest.register_node("mcl_barrels:barrel_open", { _doc_items_longdesc = S("Barrels are containers which provide 27 inventory slots."), _doc_items_usagehelp = S("To access its inventory, rightclick it. When broken, the items will drop out."), _doc_items_create_entry = false, - tiles = {"mcl_barrels_barrel_top_open.png", "mcl_barrels_barrel_bottom.png", "mcl_barrels_barrel_side.png"}, + tiles = { "mcl_barrels_barrel_top_open.png", "mcl_barrels_barrel_bottom.png", "mcl_barrels_barrel_side.png" }, paramtype = "light", paramtype2 = "facedir", drop = "mcl_barrels:barrel_closed", stack_max = 64, sounds = mcl_sounds.node_sound_wood_defaults(), - groups = {handy = 1, axey = 1, container = 2, material_wood = 1, flammable = -1, deco_block = 1, not_in_creative_inventory = 1}, + groups = { + handy = 1, + axey = 1, + container = 2, + material_wood = 1, + flammable = -1, + deco_block = 1, + not_in_creative_inventory = 1 + }, allow_metadata_inventory_move = protection_check_move, allow_metadata_inventory_take = protection_check_put_take, allow_metadata_inventory_put = protection_check_put_take, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in barrel at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in barrel at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to barrel at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to barrel at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from barrel at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from barrel at " .. minetest.pos_to_string(pos)) end, after_dig_node = drop_content, on_blast = on_blast, @@ -193,10 +211,10 @@ end) minetest.register_craft({ output = "mcl_barrels:barrel_closed", recipe = { - {"group:wood", "group:wood_slab", "group:wood"}, - {"group:wood", "", "group:wood"}, - {"group:wood", "group:wood_slab", "group:wood"}, - } + { "group:wood", "group:wood_slab", "group:wood" }, + { "group:wood", "", "group:wood" }, + { "group:wood", "group:wood_slab", "group:wood" }, + }, }) minetest.register_craft({ diff --git a/mods/ITEMS/mcl_blast_furnace/init.lua b/mods/ITEMS/mcl_blast_furnace/init.lua index e8e6e81c8..51a8f193a 100644 --- a/mods/ITEMS/mcl_blast_furnace/init.lua +++ b/mods/ITEMS/mcl_blast_furnace/init.lua @@ -1,5 +1,6 @@ - local S = minetest.get_translator(minetest.get_current_modname()) +local C = minetest.colorize +local F = minetest.formspec_escape local LIGHT_ACTIVE_FURNACE = 13 @@ -8,60 +9,82 @@ local LIGHT_ACTIVE_FURNACE = 13 -- local function active_formspec(fuel_percent, item_percent) - return "size[9,8.75]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Blast Furnace"))).."]".. - "list[context;src;2.75,0.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. - "list[context;fuel;2.75,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,2.5,1,1).. - "list[context;dst;5.75,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(5.75,1.5,1,1).. - "image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:".. - (100-fuel_percent)..":default_furnace_fire_fg.png]".. - "image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[lowpart:".. - (item_percent)..":gui_furnace_arrow_fg.png^[transformR270]".. - -- Craft guide button temporarily removed due to Minetest bug. - -- TODO: Add it back when the Minetest bug is fixed. - --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. - --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. - "listring[context;dst]".. - "listring[current_player;main]".. - "listring[context;src]".. - "listring[current_player;main]".. - "listring[context;fuel]".. - "listring[current_player;main]" + return table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Blast Furnace"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(3.5, 0.75, 1, 1), + "list[context;src;3.5,0.75;1,1;]", + + "image[3.5,2;1,1;default_furnace_fire_bg.png^[lowpart:" .. + (100 - fuel_percent) .. ":default_furnace_fire_fg.png]", + + mcl_formspec.get_itemslot_bg_v4(3.5, 3.25, 1, 1), + "list[context;fuel;3.5,3.25;1,1;]", + + "image[5.25,2;1.5,1;gui_furnace_arrow_bg.png^[lowpart:" .. + (item_percent) .. ":gui_furnace_arrow_fg.png^[transformR270]", + mcl_formspec.get_itemslot_bg_v4(7.875, 2, 1, 1, 0.2), + "list[context;dst;7.875,2;1,1;]", + + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + + -- Craft guide button temporarily removed due to Minetest bug. + -- TODO: Add it back when the Minetest bug is fixed. + --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. + --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. + + "listring[context;dst]", + "listring[current_player;main]", + "listring[context;src]", + "listring[current_player;main]", + "listring[context;fuel]", + "listring[current_player;main]", + }) end -local inactive_formspec = "size[9,8.75]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Blast Furnace"))).."]".. - "list[context;src;2.75,0.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. - "list[context;fuel;2.75,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,2.5,1,1).. - "list[context;dst;5.75,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(5.75,1.5,1,1).. - "image[2.75,1.5;1,1;default_furnace_fire_bg.png]".. - "image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[transformR270]".. +local inactive_formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Blast Furnace"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(3.5, 0.75, 1, 1), + "list[context;src;3.5,0.75;1,1;]", + + "image[3.5,2;1,1;default_furnace_fire_bg.png]", + + mcl_formspec.get_itemslot_bg_v4(3.5, 3.25, 1, 1), + "list[context;fuel;3.5,3.25;1,1;]", + + "image[5.25,2;1.5,1;gui_furnace_arrow_bg.png^[transformR270]", + + mcl_formspec.get_itemslot_bg_v4(7.875, 2, 1, 1, 0.2), + "list[context;dst;7.875,2;1,1;]", + + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + -- Craft guide button temporarily removed due to Minetest bug. -- TODO: Add it back when the Minetest bug is fixed. --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. - "listring[context;dst]".. - "listring[current_player;main]".. - "listring[context;src]".. - "listring[current_player;main]".. - "listring[context;fuel]".. - "listring[current_player;main]" + + "listring[context;dst]", + "listring[current_player;main]", + "listring[context;src]", + "listring[current_player;main]", + "listring[context;fuel]", + "listring[current_player;main]", +}) + local receive_fields = function(pos, formname, fields, sender) if fields.craftguide then @@ -71,7 +94,7 @@ end local function give_xp(pos, player) local meta = minetest.get_meta(pos) - local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2),-1.95) + local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2), -1.95) local xp = meta:get_int("xp") if xp > 0 then if player then @@ -99,7 +122,7 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player) -- Test stack with size 1 because we burn one fuel at a time local teststack = ItemStack(stack) teststack:set_count(1) - local output, decremented_input = minetest.get_craft_result({method="fuel", width=1, items={teststack}}) + local output, decremented_input = minetest.get_craft_result({ method = "fuel", width = 1, items = { teststack } }) if output.time ~= 0 then -- Only allow to place 1 item if fuel get replaced by recipe. -- This is the case for lava buckets. @@ -160,17 +183,17 @@ local function spawn_flames(pos, param2) local minrelpos, maxrelpos local dir = minetest.facedir_to_dir(param2) if dir.x > 0 then - minrelpos = { x = -0.6, y = -0.05, z = -0.25 } - maxrelpos = { x = -0.55, y = -0.45, z = 0.25 } + minrelpos = vector.new(-0.6, -0.05, -0.25) + maxrelpos = vector.new(-0.55, -0.45, 0.25) elseif dir.x < 0 then - minrelpos = { x = 0.55, y = -0.05, z = -0.25 } - maxrelpos = { x = 0.6, y = -0.45, z = 0.25 } + minrelpos = vector.new(0.55, -0.05, -0.25) + maxrelpos = vector.new(0.6, -0.45, 0.25) elseif dir.z > 0 then - minrelpos = { x = -0.25, y = -0.05, z = -0.6 } - maxrelpos = { x = 0.25, y = -0.45, z = -0.55 } + minrelpos = vector.new(-0.25, -0.05, -0.6) + maxrelpos = vector.new(0.25, 0.45, -0.55) elseif dir.z < 0 then - minrelpos = { x = -0.25, y = -0.05, z = 0.55 } - maxrelpos = { x = 0.25, y = -0.45, z = 0.6 } + minrelpos = vector.new(-0.25, -0.05, 0.55) + maxrelpos = vector.new(0.25, -0.45, 0.6) else return end @@ -179,8 +202,8 @@ local function spawn_flames(pos, param2) time = 0, minpos = vector.add(pos, minrelpos), maxpos = vector.add(pos, maxrelpos), - minvel = { x = -0.01, y = 0, z = -0.01 }, - maxvel = { x = 0.01, y = 0.1, z = 0.01 }, + minvel = vector.new(-0.01, 0, -0.01), + maxvel = vector.new(0.01, 0.1, 0.01), minexptime = 0.3, maxexptime = 0.6, minsize = 0.4, @@ -293,7 +316,7 @@ local function blast_furnace_node_timer(pos, elapsed) -- Check if we have cookable content: cookable local aftercooked - cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) + cooked, aftercooked = minetest.get_craft_result({ method = "cooking", width = 1, items = srclist }) cookable = minetest.get_item_group(inv:get_stack("src", 1):get_name(), "blast_furnace_smeltable") == 1 if cookable then -- Successful cooking requires space in dst slot and time @@ -311,7 +334,7 @@ local function blast_furnace_node_timer(pos, elapsed) if cookable and not active then -- We need to get new fuel local afterfuel - fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) + fuel, afterfuel = minetest.get_craft_result({ method = "fuel", width = 1, items = fuellist }) if fuel.time == 0 then -- No valid fuel in fuel list -- stop @@ -343,7 +366,7 @@ local function blast_furnace_node_timer(pos, elapsed) srclist = inv:get_list("src") src_time = 0 - meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count + meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count end end @@ -390,9 +413,9 @@ local function blast_furnace_node_timer(pos, elapsed) meta:set_float("fuel_time", fuel_time) meta:set_float("src_time", src_time) if srclist then - meta:set_string("src_item", src_item) + meta:set_string("src_item", src_item) else - meta:set_string("src_item", "") + meta:set_string("src_item", "") end meta:set_string("formspec", formspec) @@ -415,13 +438,14 @@ end minetest.register_node("mcl_blast_furnace:blast_furnace", { description = S("Blast Furnace"), _tt_help = S("Smelts ores faster than furnace"), - _doc_items_longdesc = S("Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, but twice as fast as a normal furnace."), + _doc_items_longdesc = S( + "Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, but twice as fast as a normal furnace."), _doc_items_usagehelp = - S("Use the blast furnace to open the furnace menu.").."\n".. - S("Place a furnace fuel in the lower slot and the source material in the upper slot.").."\n".. - S("The blast furnace will slowly use its fuel to smelt the item.").."\n".. - S("The result will be placed into the output slot at the right side.").."\n".. - S("Use the recipe book to see what ores you can smelt, what you can use as fuel and how long it will burn."), + S("Use the blast furnace to open the furnace menu.") .. "\n" .. + S("Place a furnace fuel in the lower slot and the source material in the upper slot.") .. "\n" .. + S("The blast furnace will slowly use its fuel to smelt the item.") .. "\n" .. + S("The result will be placed into the output slot at the right side.") .. "\n" .. + S("Use the recipe book to see what ores you can smelt, what you can use as fuel and how long it will burn."), _doc_items_hidden = false, tiles = { "blast_furnace_top.png", "blast_furnace_top.png", @@ -429,7 +453,7 @@ minetest.register_node("mcl_blast_furnace:blast_furnace", { "blast_furnace_side.png", "blast_furnace_front.png" }, paramtype2 = "facedir", - groups = {pickaxey=1, container=4, deco_block=1, material_stone=1}, + groups = { pickaxey = 1, container = 4, deco_block = 1, material_stone = 1 }, is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(), @@ -439,11 +463,10 @@ minetest.register_node("mcl_blast_furnace:blast_furnace", { local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() - for _, listname in ipairs({"src", "dst", "fuel"}) do + for _, listname in ipairs({ "src", "dst", "fuel" }) do local stack = inv:get_stack(listname, 1) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} - minetest.add_item(p, stack) + minetest.add_item(vector.offset(pos, math.random(0, 10) / 10 - 0.5, 0, math.random(0, 10) / 10 - 0.5), stack) end end meta:from_table(meta2) @@ -499,14 +522,16 @@ minetest.register_node("mcl_blast_furnace:blast_furnace_active", { tiles = { "blast_furnace_top.png", "blast_furnace_top.png", "blast_furnace_side.png", "blast_furnace_side.png", - "blast_furnace_side.png", {name = "blast_furnace_front_on.png", - animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 48}}, + "blast_furnace_side.png", { + name = "blast_furnace_front_on.png", + animation = { type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 48 } + }, }, paramtype2 = "facedir", paramtype = "light", light_source = LIGHT_ACTIVE_FURNACE, drop = "mcl_blast_furnace:blast_furnace", - groups = {pickaxey=1, container=4, deco_block=1, not_in_creative_inventory=1, material_stone=1}, + groups = { pickaxey = 1, container = 4, deco_block = 1, not_in_creative_inventory = 1, material_stone = 1 }, is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(), on_timer = blast_furnace_node_timer, @@ -516,10 +541,14 @@ minetest.register_node("mcl_blast_furnace:blast_furnace_active", { local meta2 = meta meta:from_table(oldmetadata) local inv = meta:get_inventory() - for _, listname in ipairs({"src", "dst", "fuel"}) do + for _, listname in ipairs({ "src", "dst", "fuel" }) do local stack = inv:get_stack(listname, 1) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = vector.new( + pos.x + math.random(0, 10) / 10 - 0.5, + pos.y, + pos.z + math.random(0, 10) / 10 - 0.5 + ) minetest.add_item(p, stack) end end @@ -550,8 +579,8 @@ minetest.register_node("mcl_blast_furnace:blast_furnace_active", { minetest.register_craft({ output = "mcl_blast_furnace:blast_furnace", recipe = { - { "mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot" }, - { "mcl_core:iron_ingot", "mcl_furnaces:furnace", "mcl_core:iron_ingot" }, + { "mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot" }, + { "mcl_core:iron_ingot", "mcl_furnaces:furnace", "mcl_core:iron_ingot" }, { "mcl_core:stone_smooth", "mcl_core:stone_smooth", "mcl_core:stone_smooth" }, } }) @@ -564,10 +593,9 @@ end minetest.register_lbm({ label = "Active blast_furnace flame particles", name = "mcl_blast_furnace:flames", - nodenames = {"mcl_blast_furnace:blast_furnace_active"}, + nodenames = { "mcl_blast_furnace:blast_furnace_active" }, run_at_every_load = true, action = function(pos, node) spawn_flames(pos, node.param2) end, }) - diff --git a/mods/ITEMS/mcl_books/init.lua b/mods/ITEMS/mcl_books/init.lua index af84feb66..e2f391b17 100644 --- a/mods/ITEMS/mcl_books/init.lua +++ b/mods/ITEMS/mcl_books/init.lua @@ -5,7 +5,7 @@ local C = minetest.colorize local max_text_length = 4500 -- TODO: Increase to 12800 when scroll bar was added to written book local max_title_length = 64 -local bookshelf_inv = minetest.settings:get_bool("mcl_bookshelf_inventories",true) +local bookshelf_inv = minetest.settings:get_bool("mcl_bookshelf_inventories", true) local header = "" if minetest.get_modpath("mcl_init") then @@ -19,7 +19,7 @@ minetest.register_craftitem("mcl_books:book", { _doc_items_longdesc = S("Books are used to make bookshelves and book and quills."), inventory_image = "default_book.png", stack_max = 64, - groups = { book=1, craftitem = 1, enchantability = 1 }, + groups = { book = 1, craftitem = 1, enchantability = 1 }, _mcl_enchanting_enchanted_tool = "mcl_enchanting:book_enchanted", }) @@ -85,18 +85,19 @@ local function write(itemstack, user, pointed_thing) local node = minetest.get_node(pointed_thing.under) if user and not user:get_player_control().sneak then if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or + itemstack end end end local text = get_text(itemstack) - local formspec = "size[8,9]".. - header.. - "background[-0.5,-0.5;9,10;mcl_books_book_bg.png]".. - "textarea[0.75,0.1;7.25,9;text;;"..minetest.formspec_escape(text).."]".. - "button[0.75,7.95;3,1;sign;"..minetest.formspec_escape(S("Sign")).."]".. - "button_exit[4.25,7.95;3,1;ok;"..minetest.formspec_escape(S("Done")).."]" + local formspec = "size[8,9]" .. + header .. + "background[-0.5,-0.5;9,10;mcl_books_book_bg.png]" .. + "textarea[0.75,0.1;7.25,9;text;;" .. minetest.formspec_escape(text) .. "]" .. + "button[0.75,7.95;3,1;sign;" .. minetest.formspec_escape(S("Sign")) .. "]" .. + "button_exit[4.25,7.95;3,1;ok;" .. minetest.formspec_escape(S("Done")) .. "]" minetest.show_formspec(user:get_player_name(), "mcl_books:writable_book", formspec) end @@ -106,17 +107,18 @@ local function read(itemstack, user, pointed_thing) local node = minetest.get_node(pointed_thing.under) if user and not user:get_player_control().sneak then if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or + itemstack end end end local text = get_text(itemstack) - local formspec = "size[8,9]".. - header.. - "background[-0.5,-0.5;9,10;mcl_books_book_bg.png]".. - "textarea[0.75,0.1;7.25,9;;"..minetest.formspec_escape(text)..";]".. - "button_exit[2.25,7.95;3,1;ok;"..minetest.formspec_escape(S("Done")).."]" + local formspec = "size[8,9]" .. + header .. + "background[-0.5,-0.5;9,10;mcl_books_book_bg.png]" .. + "textarea[0.75,0.1;7.25,9;;" .. minetest.formspec_escape(text) .. ";]" .. + "button_exit[2.25,7.95;3,1;ok;" .. minetest.formspec_escape(S("Done")) .. "]" minetest.show_formspec(user:get_player_name(), "mcl_books:written_book", formspec) end @@ -125,16 +127,18 @@ minetest.register_craftitem("mcl_books:writable_book", { description = S("Book and Quill"), _tt_help = S("Write down some notes"), _doc_items_longdesc = S("This item can be used to write down some notes."), - _doc_items_usagehelp = S("Hold it in the hand, then rightclick to read the current notes and edit then. You can edit the text as often as you like. You can also sign the book which turns it into a written book which you can stack, but it can't be edited anymore.").."\n".. - S("A book can hold up to 4500 characters. The title length is limited to 64 characters."), + _doc_items_usagehelp = S( + "Hold it in the hand, then rightclick to read the current notes and edit then. You can edit the text as often as you like. You can also sign the book which turns it into a written book which you can stack, but it can't be edited anymore.") + .. "\n" .. + S("A book can hold up to 4500 characters. The title length is limited to 64 characters."), inventory_image = "mcl_books_book_writable.png", - groups = { book=1 }, + groups = { book = 1 }, stack_max = 1, on_place = write, on_secondary_use = write, }) -minetest.register_on_player_receive_fields(function ( player, formname, fields ) +minetest.register_on_player_receive_fields(function(player, formname, fields) if ((formname == "mcl_books:writable_book") and fields and fields.text) then local stack = player:get_wielded_item() if (stack:get_name() and (stack:get_name() == "mcl_books:writable_book")) then @@ -148,14 +152,17 @@ minetest.register_on_player_receive_fields(function ( player, formname, fields ) player:set_wielded_item(stack) local name = player:get_player_name() - local formspec = "size[8,9]".. - header.. - "background[-0.5,-0.5;9,10;mcl_books_book_bg.png]".. - "field[0.75,1;7.25,1;title;"..minetest.formspec_escape(minetest.colorize("#000000", S("Enter book title:")))..";]".. - "label[0.75,1.5;"..minetest.formspec_escape(minetest.colorize("#404040", S("by @1", name))).."]".. - "button_exit[0.75,7.95;3,1;sign;"..minetest.formspec_escape(S("Sign and Close")).."]".. - "tooltip[sign;"..minetest.formspec_escape(S("Note: The book will no longer be editable after signing")).."]".. - "button[4.25,7.95;3,1;cancel;"..minetest.formspec_escape(S("Cancel")).."]" + local formspec = "size[8,9]" .. + header .. + "background[-0.5,-0.5;9,10;mcl_books_book_bg.png]" .. + "field[0.75,1;7.25,1;title;" .. + minetest.formspec_escape(minetest.colorize("#000000", S("Enter book title:"))) .. ";]" .. + "label[0.75,1.5;" .. + minetest.formspec_escape(minetest.colorize("#404040", S("by @1", name))) .. "]" .. + "button_exit[0.75,7.95;3,1;sign;" .. minetest.formspec_escape(S("Sign and Close")) .. "]" .. + "tooltip[sign;" .. + minetest.formspec_escape(S("Note: The book will no longer be editable after signing")) .. "]" .. + "button[4.25,7.95;3,1;cancel;" .. minetest.formspec_escape(S("Cancel")) .. "]" minetest.show_formspec(player:get_player_name(), "mcl_books:signing", formspec) end end @@ -181,7 +188,7 @@ minetest.register_on_player_receive_fields(function ( player, formname, fields ) player:set_wielded_item(newbook) else - minetest.log("error", "[mcl_books] "..name.." failed to sign a book!") + minetest.log("error", "[mcl_books] " .. name .. " failed to sign a book!") end elseif ((formname == "mcl_books:signing") and fields and fields.cancel) then local book = player:get_wielded_item() @@ -202,12 +209,16 @@ end -- Written Book minetest.register_craftitem("mcl_books:written_book", { description = S("Written Book"), - _doc_items_longdesc = S("Written books contain some text written by someone. They can be read and copied, but not edited."), - _doc_items_usagehelp = S("Hold it in your hand, then rightclick to read the book.").."\n\n".. - -S("To copy the text of the written book, place it into the crafting grid together with a book and quill (or multiple of those) and craft. The written book will not be consumed. Copies of copies can not be copied."), + _doc_items_longdesc = S( + "Written books contain some text written by someone. They can be read and copied, but not edited." + ), + _doc_items_usagehelp = S("Hold it in your hand, then rightclick to read the book.") .. + "\n\n" .. + S( + "To copy the text of the written book, place it into the crafting grid together with a book and quill (or multiple of those) and craft. The written book will not be consumed. Copies of copies can not be copied." + ), inventory_image = "mcl_books_book_written.png", - groups = { not_in_creative_inventory=1, book=1, no_rename=1 }, + groups = { not_in_creative_inventory = 1, book = 1, no_rename = 1 }, stack_max = 16, on_place = read, on_secondary_use = read @@ -219,19 +230,19 @@ S("To copy the text of the written book, place it into the crafting grid togethe local baq = "mcl_books:writable_book" local wb = "mcl_books:written_book" local recipes = { - {wb, baq}, - {baq, baq, wb}, - {baq, baq, wb, baq}, - {baq, baq, baq, baq, wb}, - {baq, baq, baq, baq, wb, baq}, - {baq, baq, baq, baq, wb, baq, baq}, - {baq, baq, baq, baq, wb, baq, baq, baq}, - {baq, baq, baq, baq, wb, baq, baq, baq, baq}, + { wb, baq }, + { baq, baq, wb }, + { baq, baq, wb, baq }, + { baq, baq, baq, baq, wb }, + { baq, baq, baq, baq, wb, baq }, + { baq, baq, baq, baq, wb, baq, baq }, + { baq, baq, baq, baq, wb, baq, baq, baq }, + { baq, baq, baq, baq, wb, baq, baq, baq, baq }, } -for r=#recipes, 1, -1 do +for r = #recipes, 1, -1 do minetest.register_craft({ type = "shapeless", - output = "mcl_books:written_book "..r, + output = "mcl_books:written_book " .. r, recipe = recipes[r], }) end @@ -367,6 +378,9 @@ local function protection_check_put_take(pos, listname, index, stack, player) end end +---@param pos Vector +---@param node node +---@param clicker ObjectRef local function bookshelf_gui(pos, node, clicker) if not bookshelf_inv then return end local name = minetest.get_meta(pos):get_string("name") @@ -378,18 +392,22 @@ local function bookshelf_gui(pos, node, clicker) local playername = clicker:get_player_name() minetest.show_formspec(playername, - "mcl_books:bookshelf_"..pos.x.."_"..pos.y.."_"..pos.z, + "mcl_books:bookshelf_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z, table.concat({ - "size[9,8.75]", - "label[0,0;"..F(C("#313131", name)).."]", - "list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0.5;9,3;]", - mcl_formspec.get_itemslot_bg(0, 0.5, 9, 3), - "label[0,4.0;"..F(C("#313131", S("Inventory"))).."]", - "list[current_player;main;0,4.5;9,3;9]", - mcl_formspec.get_itemslot_bg(0, 4.5, 9, 3), - "list[current_player;main;0,7.74;9,1;]", - mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1), - "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main]", + "formspec_version[4]", + "size[11.75,10.425]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, name)) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3), + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3, 0, "mcl_book_book_empty_slot.png"), + "list[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";main;0.375,0.75;9,3;]", + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + "listring[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";main]", "listring[current_player;main]", }) ) @@ -397,7 +415,7 @@ end local function close_forms(pos) local players = minetest.get_connected_players() - local formname = "mcl_books:bookshelf_"..pos.x.."_"..pos.y.."_"..pos.z + local formname = "mcl_books:bookshelf_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z for p = 1, #players do if vector.distance(players[p]:get_pos(), pos) <= 30 then minetest.close_formspec(players[p]:get_player_name(), formname) @@ -409,12 +427,18 @@ end minetest.register_node("mcl_books:bookshelf", { description = S("Bookshelf"), _doc_items_longdesc = S("Bookshelves are used for decoration."), - tiles = {"mcl_books_bookshelf_top.png", "mcl_books_bookshelf_top.png", "default_bookshelf.png"}, + tiles = { "mcl_books_bookshelf_top.png", "mcl_books_bookshelf_top.png", "default_bookshelf.png" }, stack_max = 64, is_ground_content = false, groups = { - handy=1, axey=1, deco_block=1, material_wood=1, - flammable=3, fire_encouragement=30, fire_flammability=20, container=1 + handy = 1, + axey = 1, + deco_block = 1, + material_wood = 1, + flammable = 3, + fire_encouragement = 30, + fire_flammability = 20, + container = 1 }, drop = "mcl_books:book 3", sounds = wood_sound, @@ -424,7 +448,7 @@ minetest.register_node("mcl_books:bookshelf", { on_construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - inv:set_size("main", 9*3) + inv:set_size("main", 9 * 3) end, after_place_node = function(pos, placer, itemstack, pointed_thing) minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) @@ -433,16 +457,16 @@ minetest.register_node("mcl_books:bookshelf", { allow_metadata_inventory_take = protection_check_put_take, allow_metadata_inventory_put = protection_check_put_take, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in bookshelf at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to bookshelf at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from bookshelf at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) end, after_dig_node = drop_content, on_blast = on_blast, @@ -453,9 +477,9 @@ minetest.register_node("mcl_books:bookshelf", { minetest.register_craft({ output = "mcl_books:bookshelf", recipe = { - {"group:wood", "group:wood", "group:wood"}, - {"mcl_books:book", "mcl_books:book", "mcl_books:book"}, - {"group:wood", "group:wood", "group:wood"}, + { "group:wood", "group:wood", "group:wood" }, + { "mcl_books:book", "mcl_books:book", "mcl_books:book" }, + { "group:wood", "group:wood", "group:wood" }, } }) @@ -464,4 +488,3 @@ minetest.register_craft({ recipe = "mcl_books:bookshelf", burntime = 15, }) - diff --git a/mods/ITEMS/mcl_chests/init.lua b/mods/ITEMS/mcl_chests/init.lua index 38437c73f..59ed2ba09 100644 --- a/mods/ITEMS/mcl_chests/init.lua +++ b/mods/ITEMS/mcl_chests/init.lua @@ -1,41 +1,50 @@ local S = minetest.get_translator(minetest.get_current_modname()) +local F = minetest.formspec_escape +local C = minetest.colorize + +local string = string +local table = table +local math = math + +local sf = string.format + local mod_doc = minetest.get_modpath("doc") -- Christmas chest setup local it_is_christmas = false local date = os.date("*t") if ( - date.month == 12 and ( - date.day == 24 or - date.day == 25 or - date.day == 26 - ) -) then + date.month == 12 and ( + date.day == 24 or + date.day == 25 or + date.day == 26 + ) + ) then it_is_christmas = true end -local tiles_chest_normal_small = {"mcl_chests_normal.png"} -local tiles_chest_normal_double = {"mcl_chests_normal_double.png"} +local tiles_chest_normal_small = { "mcl_chests_normal.png" } +local tiles_chest_normal_double = { "mcl_chests_normal_double.png" } if it_is_christmas then - tiles_chest_normal_small = {"mcl_chests_normal_present.png^mcl_chests_noise.png"} - tiles_chest_normal_double = {"mcl_chests_normal_double_present.png^mcl_chests_noise_double.png"} + tiles_chest_normal_small = { "mcl_chests_normal_present.png^mcl_chests_noise.png" } + tiles_chest_normal_double = { "mcl_chests_normal_double_present.png^mcl_chests_noise_double.png" } end -local tiles_chest_trapped_small = {"mcl_chests_trapped.png"} -local tiles_chest_trapped_double = {"mcl_chests_trapped_double.png"} +local tiles_chest_trapped_small = { "mcl_chests_trapped.png" } +local tiles_chest_trapped_double = { "mcl_chests_trapped_double.png" } if it_is_christmas then - tiles_chest_trapped_small = {"mcl_chests_trapped_present.png^mcl_chests_noise.png"} - tiles_chest_trapped_double = {"mcl_chests_trapped_double_present.png^mcl_chests_noise_double.png"} + tiles_chest_trapped_small = { "mcl_chests_trapped_present.png^mcl_chests_noise.png" } + tiles_chest_trapped_double = { "mcl_chests_trapped_double_present.png^mcl_chests_noise_double.png" } end -local tiles_chest_ender_small = {"mcl_chests_ender.png"} +local tiles_chest_ender_small = { "mcl_chests_ender.png" } -local ender_chest_texture = {"mcl_chests_ender.png"} +local ender_chest_texture = { "mcl_chests_ender.png" } if it_is_christmas then - tiles_chest_ender_small = {"mcl_chests_ender_present.png^mcl_chests_noise.png"} - ender_chest_texture = {"mcl_chests_ender_present.png"} + tiles_chest_ender_small = { "mcl_chests_ender_present.png^mcl_chests_noise.png" } + ender_chest_texture = { "mcl_chests_ender_present.png" } end -- Chest Entity @@ -43,14 +52,14 @@ local animate_chests = (minetest.settings:get_bool("animated_chests") ~= false) local entity_animations = { shulker = { speed = 50, - open = {x = 45, y = 95}, - close = {x = 95, y = 145}, + open = { x = 45, y = 95 }, + close = { x = 95, y = 145 }, }, chest = { speed = 25, - open = {x = 0, y = 7}, - close = {x = 13, y = 20}, - } + open = { x = 0, y = 7 }, + close = { x = 13, y = 20 }, + }, } minetest.register_entity("mcl_chests:chest", { @@ -72,7 +81,8 @@ minetest.register_entity("mcl_chests:chest", { self.players[playername] = true if not self.is_open then self:set_animation("open") - minetest.sound_play(self.sound_prefix .. "_open", {pos=self.node_pos, gain=0.5, max_hear_distance = 16}, true) + minetest.sound_play(self.sound_prefix .. "_open", { pos = self.node_pos, gain = 0.5, max_hear_distance = 16 }, + true) self.is_open = true end end, @@ -85,7 +95,9 @@ minetest.register_entity("mcl_chests:chest", { return end self:set_animation("close") - minetest.sound_play(self.sound_prefix .. "_close", {pos=self.node_pos, gain=0.3, max_hear_distance = 16}, true) + minetest.sound_play(self.sound_prefix .. "_close", + { pos = self.node_pos, gain = 0.3, max_hear_distance = 16 }, + true) self.is_open = false end end, @@ -124,7 +136,7 @@ minetest.register_entity("mcl_chests:chest", { end, on_activate = function(self) - self.object:set_armor_groups({immortal = 1}) + self.object:set_armor_groups({ immortal = 1 }) self.players = {} end, @@ -136,7 +148,7 @@ minetest.register_entity("mcl_chests:chest", { }) local function get_entity_pos(pos, dir, double) - pos = vector.new(pos) + pos = vector.copy(pos) if double then local add, mul, vec, cross = vector.add, vector.multiply, vector.new, vector.cross pos = add(pos, mul(cross(dir, vec(0, 1, 0)), -0.5)) @@ -158,7 +170,8 @@ local function get_entity_info(pos, param2, double, dir, entity_pos) return dir, get_entity_pos(pos, dir, double) end -local function create_entity(pos, node_name, textures, param2, double, sound_prefix, mesh_prefix, animation_type, dir, entity_pos) +local function create_entity(pos, node_name, textures, param2, double, sound_prefix, mesh_prefix, animation_type, dir, + entity_pos) dir, entity_pos = get_entity_info(pos, param2, double, dir, entity_pos) local obj = minetest.add_entity(entity_pos, "mcl_chests:chest") local luaentity = obj:get_luaentity() @@ -166,9 +179,12 @@ local function create_entity(pos, node_name, textures, param2, double, sound_pre return luaentity end -local function find_or_create_entity(pos, node_name, textures, param2, double, sound_prefix, mesh_prefix, animation_type, dir, entity_pos) +local function find_or_create_entity(pos, node_name, textures, param2, double, sound_prefix, mesh_prefix, animation_type + , dir, entity_pos) dir, entity_pos = get_entity_info(pos, param2, double, dir, entity_pos) - return find_entity(entity_pos) or create_entity(pos, node_name, textures, param2, double, sound_prefix, mesh_prefix, animation_type, dir, entity_pos) + return find_entity(entity_pos) or + create_entity(pos, node_name, textures, param2, double, sound_prefix, mesh_prefix, animation_type, dir, + entity_pos) end local no_rotate, simple_rotate @@ -179,7 +195,9 @@ if minetest.get_modpath("screwdriver") then local nodename = node.name local nodedef = minetest.registered_nodes[nodename] local dir = minetest.facedir_to_dir(new_param2) - find_or_create_entity(pos, nodename, nodedef._chest_entity_textures, new_param2, false, nodedef._chest_entity_sound, nodedef._chest_entity_mesh, nodedef._chest_entity_animation_type, dir):set_yaw(dir) + find_or_create_entity(pos, nodename, nodedef._chest_entity_textures, new_param2, false, + nodedef._chest_entity_sound, + nodedef._chest_entity_mesh, nodedef._chest_entity_animation_type, dir):set_yaw(dir) else return false end @@ -204,10 +222,21 @@ end]] -- To be called if a player opened a chest local function player_chest_open(player, pos, node_name, textures, param2, double, sound, mesh, shulker) local name = player:get_player_name() - open_chests[name] = {pos = pos, node_name = node_name, textures = textures, param2 = param2, double = double, sound = sound, mesh = mesh, shulker = shulker} + open_chests[name] = { + pos = pos, + node_name = node_name, + textures = textures, + param2 = param2, + double = double, + sound = sound, + mesh = mesh, + shulker = shulker + } if animate_chests then local dir = minetest.facedir_to_dir(param2) - find_or_create_entity(pos, node_name, textures, param2, double, sound, mesh, shulker and "shulker" or "chest", dir):open(name) + find_or_create_entity(pos, node_name, textures, param2, double, sound, mesh, shulker and "shulker" or "chest", + dir): + open(name) end end @@ -221,6 +250,7 @@ local function protection_check_move(pos, from_list, from_index, to_list, to_ind return count end end + local function protection_check_put_take(pos, listname, index, stack, player) local name = player:get_player_name() if minetest.is_protected(pos, name) then @@ -238,24 +268,27 @@ local function chest_update_after_close(pos) local node = minetest.get_node(pos) if node.name == "mcl_chests:trapped_chest_on_small" then - minetest.swap_node(pos, {name="mcl_chests:trapped_chest_small", param2 = node.param2}) - find_or_create_entity(pos, "mcl_chests:trapped_chest_small", {"mcl_chests_trapped.png"}, node.param2, false, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_small") + minetest.swap_node(pos, { name = "mcl_chests:trapped_chest_small", param2 = node.param2 }) + find_or_create_entity(pos, "mcl_chests:trapped_chest_small", { "mcl_chests_trapped.png" }, node.param2, false, + "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_small") mesecon.receptor_off(pos, trapped_chest_mesecons_rules) elseif node.name == "mcl_chests:trapped_chest_on_left" then - minetest.swap_node(pos, {name="mcl_chests:trapped_chest_left", param2 = node.param2}) - find_or_create_entity(pos, "mcl_chests:trapped_chest_left", tiles_chest_trapped_double, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left") + minetest.swap_node(pos, { name = "mcl_chests:trapped_chest_left", param2 = node.param2 }) + find_or_create_entity(pos, "mcl_chests:trapped_chest_left", tiles_chest_trapped_double, node.param2, true, + "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left") mesecon.receptor_off(pos, trapped_chest_mesecons_rules) local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left") - minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_right", param2 = node.param2}) + minetest.swap_node(pos_other, { name = "mcl_chests:trapped_chest_right", param2 = node.param2 }) mesecon.receptor_off(pos_other, trapped_chest_mesecons_rules) elseif node.name == "mcl_chests:trapped_chest_on_right" then - minetest.swap_node(pos, {name="mcl_chests:trapped_chest_right", param2 = node.param2}) + minetest.swap_node(pos, { name = "mcl_chests:trapped_chest_right", param2 = node.param2 }) mesecon.receptor_off(pos, trapped_chest_mesecons_rules) local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right") - minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_left", param2 = node.param2}) - find_or_create_entity(pos_other, "mcl_chests:trapped_chest_left", tiles_chest_trapped_double, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left") + minetest.swap_node(pos_other, { name = "mcl_chests:trapped_chest_left", param2 = node.param2 }) + find_or_create_entity(pos_other, "mcl_chests:trapped_chest_left", tiles_chest_trapped_double, node.param2, true, + "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left") mesecon.receptor_off(pos_other, trapped_chest_mesecons_rules) end end @@ -268,7 +301,9 @@ local function player_chest_close(player) return end if animate_chests then - find_or_create_entity(open_chest.pos, open_chest.node_name, open_chest.textures, open_chest.param2, open_chest.double, open_chest.sound, open_chest.mesh, open_chest.shulker and "shulker" or "chest"):close(name) + find_or_create_entity(open_chest.pos, open_chest.node_name, open_chest.textures, open_chest.param2, + open_chest.double, + open_chest.sound, open_chest.mesh, open_chest.shulker and "shulker" or "chest"):close(name) end chest_update_after_close(open_chest.pos) @@ -276,12 +311,14 @@ local function player_chest_close(player) end -- This is a helper function to register both chests and trapped chests. Trapped chests will make use of the additional parameters -local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tiles_table, hidden, mesecons, on_rightclick_addendum, on_rightclick_addendum_left, on_rightclick_addendum_right, drop, canonical_basename) +local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tiles_table, hidden, mesecons, + on_rightclick_addendum, on_rightclick_addendum_left, on_rightclick_addendum_right, drop, + canonical_basename) -- START OF register_chest FUNCTION BODY if not drop then - drop = "mcl_chests:"..basename + drop = "mcl_chests:" .. basename else - drop = "mcl_chests:"..drop + drop = "mcl_chests:" .. drop end -- The basename of the "canonical" version of the node, if set (e.g.: trapped_chest_on → trapped_chest). -- Used to get a shared formspec ID and to swap the node back to the canonical version in on_construct. @@ -347,12 +384,12 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile return stack:get_count() - leftover:get_count() end - local small_name = "mcl_chests:"..basename.."_small" + local small_name = "mcl_chests:" .. basename .. "_small" local small_textures = tiles_table.small - local left_name = "mcl_chests:"..basename.."_left" + local left_name = "mcl_chests:" .. basename .. "_left" local left_textures = tiles_table.double - minetest.register_node("mcl_chests:"..basename, { + minetest.register_node("mcl_chests:" .. basename, { description = desc, _tt_help = tt_help, _doc_items_longdesc = longdesc, @@ -361,12 +398,11 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile drawtype = "mesh", mesh = "mcl_chests_chest.b3d", tiles = small_textures, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + use_texture_alpha = "opaque", paramtype = "light", paramtype2 = "facedir", - stack_max = 64, sounds = mcl_sounds.node_sound_wood_defaults(), - groups = {deco_block=1}, + groups = { deco_block = 1 }, on_construct = function(pos, node) local node = minetest.get_node(pos) node.name = small_name @@ -379,9 +415,10 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile local function close_forms(canonical_basename, pos) local players = minetest.get_connected_players() - for p=1, #players do + for p = 1, #players do if vector.distance(players[p]:get_pos(), pos) <= 30 then - minetest.close_formspec(players[p]:get_player_name(), "mcl_chests:"..canonical_basename.."_"..pos.x.."_"..pos.y.."_"..pos.z) + minetest.close_formspec(players[p]:get_player_name(), + "mcl_chests:" .. canonical_basename .. "_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z) end end end @@ -395,19 +432,27 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile drawtype = "nodebox", node_box = { type = "fixed", - fixed = {-0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375}, + fixed = { -0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375 }, }, - tiles = {"blank.png^[resize:16x16"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + tiles = { "blank.png^[resize:16x16" }, + use_texture_alpha = "clip", _chest_entity_textures = small_textures, _chest_entity_sound = "default_chest", _chest_entity_mesh = "mcl_chests_chest", _chest_entity_animation_type = "chest", paramtype = "light", paramtype2 = "facedir", - stack_max = 64, drop = drop, - groups = {handy=1,axey=1, container=2, deco_block=1, material_wood=1,flammable=-1,chest_entity=1, not_in_creative_inventory=1}, + groups = { + handy = 1, + axey = 1, + container = 2, + deco_block = 1, + material_wood = 1, + flammable = -1, + chest_entity = 1, + not_in_creative_inventory = 1 + }, is_ground_content = false, sounds = mcl_sounds.node_sound_wood_defaults(), on_construct = function(pos) @@ -424,7 +469,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile meta:set_string("workaround", nil) -- Done to keep metadata clean -- END OF WORKAROUND -- local inv = meta:get_inventory() - inv:set_size("main", 9*3) + inv:set_size("main", 9 * 3) --[[ The "input" list is *another* workaround (hahahaha!) around the fact that Minetest does not support listrings to put items into an alternative list if the first one happens to be full. See . @@ -435,19 +480,26 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile -- BEGIN OF LISTRING WORKAROUND inv:set_size("input", 1) -- END OF LISTRING WORKAROUND - if minetest.get_node(mcl_util.get_double_container_neighbor_pos(pos, param2, "right")).name == "mcl_chests:"..canonical_basename.."_small" then - minetest.swap_node(pos, {name="mcl_chests:"..canonical_basename.."_right",param2=param2}) + if minetest.get_node(mcl_util.get_double_container_neighbor_pos(pos, param2, "right")).name == + "mcl_chests:" .. canonical_basename .. "_small" then + minetest.swap_node(pos, { name = "mcl_chests:" .. canonical_basename .. "_right", param2 = param2 }) local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "right") - minetest.swap_node(p, { name = "mcl_chests:"..canonical_basename.."_left", param2 = param2 }) - create_entity(p, "mcl_chests:"..canonical_basename.."_left", left_textures, param2, true, "default_chest", "mcl_chests_chest", "chest") - elseif minetest.get_node(mcl_util.get_double_container_neighbor_pos(pos, param2, "left")).name == "mcl_chests:"..canonical_basename.."_small" then - minetest.swap_node(pos, {name="mcl_chests:"..canonical_basename.."_left",param2=param2}) - create_entity(pos, "mcl_chests:"..canonical_basename.."_left", left_textures, param2, true, "default_chest", "mcl_chests_chest", "chest") + minetest.swap_node(p, { name = "mcl_chests:" .. canonical_basename .. "_left", param2 = param2 }) + create_entity(p, "mcl_chests:" .. canonical_basename .. "_left", left_textures, param2, true, + "default_chest", + "mcl_chests_chest", "chest") + elseif minetest.get_node(mcl_util.get_double_container_neighbor_pos(pos, param2, "left")).name == + "mcl_chests:" .. canonical_basename .. "_small" then + minetest.swap_node(pos, { name = "mcl_chests:" .. canonical_basename .. "_left", param2 = param2 }) + create_entity(pos, "mcl_chests:" .. canonical_basename .. "_left", left_textures, param2, true, + "default_chest", + "mcl_chests_chest", "chest") local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "left") - minetest.swap_node(p, { name = "mcl_chests:"..canonical_basename.."_right", param2 = param2 }) + minetest.swap_node(p, { name = "mcl_chests:" .. canonical_basename .. "_right", param2 = param2 }) else - minetest.swap_node(pos, { name = "mcl_chests:"..canonical_basename.."_small", param2 = param2 }) - create_entity(pos, small_name, small_textures, param2, false, "default_chest", "mcl_chests_chest", "chest") + minetest.swap_node(pos, { name = "mcl_chests:" .. canonical_basename .. "_small", param2 = param2 }) + create_entity(pos, small_name, small_textures, param2, false, "default_chest", "mcl_chests_chest", + "chest") end end, after_place_node = function(pos, placer, itemstack, pointed_thing) @@ -459,28 +511,28 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile allow_metadata_inventory_take = protection_check_put_take, allow_metadata_inventory_put = protection_check_put_take, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in chest at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to chest at " .. minetest.pos_to_string(pos)) -- BEGIN OF LISTRING WORKAROUND if listname == "input" then - local inv = minetest.get_inventory({type="node", pos=pos}) + local inv = minetest.get_inventory({ type = "node", pos = pos }) inv:add_item("main", stack) end -- END OF LISTRING WORKAROUND end, on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from chest at " .. minetest.pos_to_string(pos)) end, _mcl_blast_resistance = 2.5, _mcl_hardness = 2.5, on_rightclick = function(pos, node, clicker) - if minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name].groups.opaque == 1 then + if minetest.registered_nodes[minetest.get_node({ x = pos.x, y = pos.y + 1, z = pos.z }).name].groups.opaque == 1 then -- won't open if there is no space from the top return false end @@ -490,24 +542,31 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile end minetest.show_formspec(clicker:get_player_name(), - "mcl_chests:"..canonical_basename.."_"..pos.x.."_"..pos.y.."_"..pos.z, - "size[9,8.75]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", name)).."]".. - "list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0.5;9,3;]".. - mcl_formspec.get_itemslot_bg(0,0.5,9,3).. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main]".. - "listring[current_player;main]") + sf("mcl_chests:%s_%s_%s_%s", canonical_basename, pos.x, pos.y, pos.z), + table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, name)) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3), + sf("list[nodemeta:%s,%s,%s;main;0.375,0.75;9,3;]", pos.x, pos.y, pos.z), + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + sf("listring[nodemeta:%s,%s,%s;main]", pos.x, pos.y, pos.z), + "listring[current_player;main]", + }) + ) if on_rightclick_addendum then on_rightclick_addendum(pos, node, clicker) end - player_chest_open(clicker, pos, small_name, small_textures, node.param2, false, "default_chest", "mcl_chests_chest") + player_chest_open(clicker, pos, small_name, small_textures, node.param2, false, "default_chest", + "mcl_chests_chest") end, on_destruct = function(pos) @@ -521,17 +580,26 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile drawtype = "nodebox", node_box = { type = "fixed", - fixed = {-0.4375, -0.5, -0.4375, 0.5, 0.375, 0.4375}, + fixed = { -0.4375, -0.5, -0.4375, 0.5, 0.375, 0.4375 }, }, - tiles = {"blank.png^[resize:16x16"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + tiles = { "blank.png^[resize:16x16" }, + use_texture_alpha = "clip", _chest_entity_textures = left_textures, _chest_entity_sound = "default_chest", _chest_entity_mesh = "mcl_chests_chest", _chest_entity_animation_type = "chest", paramtype = "light", paramtype2 = "facedir", - groups = {handy=1,axey=1, container=5,not_in_creative_inventory=1, material_wood=1,flammable=-1,chest_entity=1,double_chest=1}, + groups = { + handy = 1, + axey = 1, + container = 5, + not_in_creative_inventory = 1, + material_wood = 1, + flammable = -1, + chest_entity = 1, + double_chest = 1 + }, drop = drop, is_ground_content = false, sounds = mcl_sounds.node_sound_wood_defaults(), @@ -539,8 +607,8 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile local n = minetest.get_node(pos) local param2 = n.param2 local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "left") - if not p or minetest.get_node(p).name ~= "mcl_chests:"..canonical_basename.."_right" then - n.name = "mcl_chests:"..canonical_basename.."_small" + if not p or minetest.get_node(p).name ~= "mcl_chests:" .. canonical_basename .. "_right" then + n.name = "mcl_chests:" .. canonical_basename .. "_small" minetest.swap_node(pos, n) end create_entity(pos, left_name, left_textures, param2, true, "default_chest", "mcl_chests_chest", "chest") @@ -558,7 +626,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile local param2 = n.param2 local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "left") - if not p or minetest.get_node(p).name ~= "mcl_chests:"..basename.."_right" then + if not p or minetest.get_node(p).name ~= "mcl_chests:" .. basename .. "_right" then return end close_forms(canonical_basename, p) @@ -575,11 +643,11 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile if minetest.is_protected(pos, name) then minetest.record_protection_violation(pos, name) return 0 - -- BEGIN OF LISTRING WORKAROUND + -- BEGIN OF LISTRING WORKAROUND elseif listname == "input" then - local inv = minetest.get_inventory({type="node", pos=pos}) + local inv = minetest.get_inventory({ type = "node", pos = pos }) local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "left") - local other_inv = minetest.get_inventory({type="node", pos=other_pos}) + local other_inv = minetest.get_inventory({ type = "node", pos = other_pos }) return limit_put(stack, inv, other_inv) --[[if inv:room_for_item("main", stack) then return -1 @@ -590,24 +658,25 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile else return 0 end - end]]-- - -- END OF LISTRING WORKAROUND + end]] + -- + -- END OF LISTRING WORKAROUND else return stack:get_count() end end, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in chest at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to chest at " .. minetest.pos_to_string(pos)) -- BEGIN OF LISTRING WORKAROUND if listname == "input" then - local inv = minetest.get_inventory({type="node", pos=pos}) + local inv = minetest.get_inventory({ type = "node", pos = pos }) local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "left") - local other_inv = minetest.get_inventory({type="node", pos=other_pos}) + local other_inv = minetest.get_inventory({ type = "node", pos = other_pos }) inv:set_stack("input", 1, nil) @@ -616,16 +685,17 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile -- END OF LISTRING WORKAROUND end, on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from chest at " .. minetest.pos_to_string(pos)) end, _mcl_blast_resistance = 2.5, _mcl_hardness = 2.5, on_rightclick = function(pos, node, clicker) local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left") - local above_def = minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name] - local above_def_other = minetest.registered_nodes[minetest.get_node({x = pos_other.x, y = pos_other.y + 1, z = pos_other.z}).name] + local above_def = minetest.registered_nodes[minetest.get_node({ x = pos.x, y = pos.y + 1, z = pos.z }).name] + local above_def_other = minetest.registered_nodes[ + minetest.get_node({ x = pos_other.x, y = pos_other.y + 1, z = pos_other.z }).name] if not above_def or above_def.groups.opaque == 1 or not above_def_other or above_def_other.groups.opaque == 1 then -- won't open if there is no space from the top @@ -641,48 +711,64 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile end minetest.show_formspec(clicker:get_player_name(), - "mcl_chests:"..canonical_basename.."_"..pos.x.."_"..pos.y.."_"..pos.z, - "size[9,11.5]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", name)).."]".. - "list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0.5;9,3;]".. - mcl_formspec.get_itemslot_bg(0,0.5,9,3).. - "list[nodemeta:"..pos_other.x..","..pos_other.y..","..pos_other.z..";main;0,3.5;9,3;]".. - mcl_formspec.get_itemslot_bg(0,3.5,9,3).. - "label[0,7;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,7.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,7.5,9,3).. - "list[current_player;main;0,10.75;9,1;]".. - mcl_formspec.get_itemslot_bg(0,10.75,9,1).. - -- BEGIN OF LISTRING WORKAROUND - "listring[current_player;main]".. - "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";input]".. - -- END OF LISTRING WORKAROUND - "listring[current_player;main]".. - "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main]".. - "listring[current_player;main]".. - "listring[nodemeta:"..pos_other.x..","..pos_other.y..","..pos_other.z..";main]") + sf("mcl_chests:%s_%s_%s_%s", canonical_basename, pos.x, pos.y, pos.z), + table.concat({ + "formspec_version[4]", + "size[11.75,14.15]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, name)) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3), + sf("list[nodemeta:%s,%s,%s;main;0.375,0.75;9,3;]", pos.x, pos.y, pos.z), + mcl_formspec.get_itemslot_bg_v4(0.375, 4.5, 9, 3), + sf("list[nodemeta:%s,%s,%s;main;0.375,4.5;9,3;]", pos_other.x, pos_other.y, pos_other.z), + "label[0.375,8.45;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 8.825, 9, 3), + "list[current_player;main;0.375,8.825;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 12.775, 9, 1), + "list[current_player;main;0.375,12.775;9,1;]", + + --BEGIN OF LISTRING WORKAROUND + "listring[current_player;main]", + sf("listring[nodemeta:%s,%s,%s;input]", pos.x, pos.y, pos.z), + --END OF LISTRING WORKAROUND + "listring[current_player;main]" .. + sf("listring[nodemeta:%s,%s,%s;main]", pos.x, pos.y, pos.z), + "listring[current_player;main]", + sf("listring[nodemeta:%s,%s,%s;main]", pos_other.x, pos_other.y, pos_other.z), + }) + ) if on_rightclick_addendum_left then on_rightclick_addendum_left(pos, node, clicker) end - player_chest_open(clicker, pos, left_name, left_textures, node.param2, true, "default_chest", "mcl_chests_chest") + player_chest_open(clicker, pos, left_name, left_textures, node.param2, true, "default_chest", + "mcl_chests_chest") end, mesecons = mesecons, on_rotate = no_rotate, }) - minetest.register_node("mcl_chests:"..basename.."_right", { + minetest.register_node("mcl_chests:" .. basename .. "_right", { drawtype = "nodebox", paramtype = "light", paramtype2 = "facedir", node_box = { type = "fixed", - fixed = {-0.5, -0.5, -0.4375, 0.4375, 0.375, 0.4375}, + fixed = { -0.5, -0.5, -0.4375, 0.4375, 0.375, 0.4375 }, + }, + tiles = { "blank.png^[resize:16x16" }, + use_texture_alpha = "clip", + groups = { + handy = 1, + axey = 1, + container = 6, + not_in_creative_inventory = 1, + material_wood = 1, + flammable = -1, + double_chest = 2 }, - tiles = {"blank.png^[resize:16x16"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, - groups = {handy=1,axey=1, container=6,not_in_creative_inventory=1, material_wood=1,flammable=-1,double_chest=2}, drop = drop, is_ground_content = false, sounds = mcl_sounds.node_sound_wood_defaults(), @@ -690,8 +776,8 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile local n = minetest.get_node(pos) local param2 = n.param2 local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "right") - if not p or minetest.get_node(p).name ~= "mcl_chests:"..canonical_basename.."_left" then - n.name = "mcl_chests:"..canonical_basename.."_small" + if not p or minetest.get_node(p).name ~= "mcl_chests:" .. canonical_basename .. "_left" then + n.name = "mcl_chests:" .. canonical_basename .. "_small" minetest.swap_node(pos, n) end end, @@ -708,7 +794,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile local param2 = n.param2 local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "right") - if not p or minetest.get_node(p).name ~= "mcl_chests:"..basename.."_left" then + if not p or minetest.get_node(p).name ~= "mcl_chests:" .. basename .. "_left" then return end close_forms(canonical_basename, p) @@ -725,11 +811,11 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile if minetest.is_protected(pos, name) then minetest.record_protection_violation(pos, name) return 0 - -- BEGIN OF LISTRING WORKAROUND + -- BEGIN OF LISTRING WORKAROUND elseif listname == "input" then local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "right") - local other_inv = minetest.get_inventory({type="node", pos=other_pos}) - local inv = minetest.get_inventory({type="node", pos=pos}) + local other_inv = minetest.get_inventory({ type = "node", pos = other_pos }) + local inv = minetest.get_inventory({ type = "node", pos = pos }) --[[if other_inv:room_for_item("main", stack) then return -1 else @@ -740,23 +826,23 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile end end--]] return limit_put(stack, other_inv, inv) - -- END OF LISTRING WORKAROUND + -- END OF LISTRING WORKAROUND else return stack:get_count() end end, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in chest at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to chest at " .. minetest.pos_to_string(pos)) -- BEGIN OF LISTRING WORKAROUND if listname == "input" then local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "right") - local other_inv = minetest.get_inventory({type="node", pos=other_pos}) - local inv = minetest.get_inventory({type="node", pos=pos}) + local other_inv = minetest.get_inventory({ type = "node", pos = other_pos }) + local inv = minetest.get_inventory({ type = "node", pos = pos }) inv:set_stack("input", 1, nil) @@ -765,18 +851,20 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile -- END OF LISTRING WORKAROUND end, on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from chest at " .. minetest.pos_to_string(pos)) end, _mcl_blast_resistance = 2.5, _mcl_hardness = 2.5, on_rightclick = function(pos, node, clicker) local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right") - if minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name].groups.opaque == 1 - or minetest.registered_nodes[minetest.get_node({x = pos_other.x, y = pos_other.y + 1, z = pos_other.z}).name].groups.opaque == 1 then - -- won't open if there is no space from the top - return false + if minetest.registered_nodes[minetest.get_node(vector.offset(pos, 0, 1, 0)).name].groups.opaque == 1 + or + minetest.registered_nodes[minetest.get_node(vector.offset(pos_other, 0, 1, 0)).name].groups.opaque + == 1 then + -- won't open if there is no space from the top + return false end local name = minetest.get_meta(pos_other):get_string("name") @@ -788,41 +876,48 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile end minetest.show_formspec(clicker:get_player_name(), - "mcl_chests:"..canonical_basename.."_"..pos.x.."_"..pos.y.."_"..pos.z, + sf("mcl_chests:%s_%s_%s_%s", canonical_basename, pos.x, pos.y, pos.z), + table.concat({ + "formspec_version[4]", + "size[11.75,14.15]", - "size[9,11.5]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", name)).."]".. - "list[nodemeta:"..pos_other.x..","..pos_other.y..","..pos_other.z..";main;0,0.5;9,3;]".. - mcl_formspec.get_itemslot_bg(0,0.5,9,3).. - "list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,3.5;9,3;]".. - mcl_formspec.get_itemslot_bg(0,3.5,9,3).. - "label[0,7;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,7.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,7.5,9,3).. - "list[current_player;main;0,10.75;9,1;]".. - mcl_formspec.get_itemslot_bg(0,10.75,9,1).. - -- BEGIN OF LISTRING WORKAROUND - "listring[current_player;main]".. - "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";input]".. - -- END OF LISTRING WORKAROUND - "listring[current_player;main]".. - "listring[nodemeta:"..pos_other.x..","..pos_other.y..","..pos_other.z..";main]".. - "listring[current_player;main]".. - "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main]") + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, name)) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3), + sf("list[nodemeta:%s,%s,%s;main;0.375,0.75;9,3;]", pos_other.x, pos_other.y, pos_other.z), + mcl_formspec.get_itemslot_bg_v4(0.375, 4.5, 9, 3), + sf("list[nodemeta:%s,%s,%s;main;0.375,4.5;9,3;]", pos.x, pos.y, pos.z), + "label[0.375,8.45;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 8.825, 9, 3), + "list[current_player;main;0.375,8.825;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 12.775, 9, 1), + "list[current_player;main;0.375,12.775;9,1;]", + + --BEGIN OF LISTRING WORKAROUND + "listring[current_player;main]", + sf("listring[nodemeta:%s,%s,%s;input]", pos.x, pos.y, pos.z), + --END OF LISTRING WORKAROUND + "listring[current_player;main]" .. + sf("listring[nodemeta:%s,%s,%s;main]", pos_other.x, pos_other.y, pos_other.z), + "listring[current_player;main]", + sf("listring[nodemeta:%s,%s,%s;main]", pos.x, pos.y, pos.z), + }) + ) if on_rightclick_addendum_right then on_rightclick_addendum_right(pos, node, clicker) end - player_chest_open(clicker, pos_other, left_name, left_textures, node.param2, true, "default_chest", "mcl_chests_chest") + player_chest_open(clicker, pos_other, left_name, left_textures, node.param2, true, "default_chest", + "mcl_chests_chest") end, mesecons = mesecons, on_rotate = no_rotate, }) if mod_doc then - doc.add_entry_alias("nodes", small_name, "nodes", "mcl_chests:"..basename.."_left") - doc.add_entry_alias("nodes", small_name, "nodes", "mcl_chests:"..basename.."_right") + doc.add_entry_alias("nodes", small_name, "nodes", "mcl_chests:" .. basename .. "_left") + doc.add_entry_alias("nodes", small_name, "nodes", "mcl_chests:" .. basename .. "_right") end -- END OF register_chest FUNCTION BODY @@ -838,6 +933,15 @@ register_chest("chest", { small = tiles_chest_normal_small, double = tiles_chest_normal_double, + inv = { "default_chest_top.png", "mcl_chests_chest_bottom.png", + "mcl_chests_chest_right.png", "mcl_chests_chest_left.png", + "mcl_chests_chest_back.png", "default_chest_front.png" }, + --[[left = {"default_chest_top_big.png", "default_chest_top_big.png", + "mcl_chests_chest_right.png", "mcl_chests_chest_left.png", + "default_chest_side_big.png^[transformFX", "default_chest_front_big.png"}, + right = {"default_chest_top_big.png^[transformFX", "default_chest_top_big.png^[transformFX", + "mcl_chests_chest_right.png", "mcl_chests_chest_left.png", + "default_chest_side_big.png", "default_chest_front_big.png^[transformFX"},]] -- }, false ) @@ -851,48 +955,57 @@ register_chest("trapped_chest", S("Trapped Chest"), S("A trapped chest is a container which provides 27 inventory slots. When it is opened, it sends a redstone signal to its adjacent blocks as long it stays open. Trapped chests can be turned into large trapped chests with double the capacity by placing two trapped chests next to each other."), chestusage, - S("27 inventory slots") .. "\n" .. S("Can be combined to a large chest") .. "\n" .. S("Emits a redstone signal when opened"), + S("27 inventory slots") .. + "\n" .. S("Can be combined to a large chest") .. "\n" .. S("Emits a redstone signal when opened"), traptiles, nil, - {receptor = { - state = mesecon.state.off, - rules = trapped_chest_mesecons_rules, - }}, + { + receptor = { + state = mesecon.state.off, + rules = trapped_chest_mesecons_rules, + }, + }, function(pos, node, clicker) - minetest.swap_node(pos, {name="mcl_chests:trapped_chest_on_small", param2 = node.param2}) - find_or_create_entity(pos, "mcl_chests:trapped_chest_on_small", {"mcl_chests_trapped.png"}, node.param2, false, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_small") + minetest.swap_node(pos, { name = "mcl_chests:trapped_chest_on_small", param2 = node.param2 }) + find_or_create_entity(pos, "mcl_chests:trapped_chest_on_small", { "mcl_chests_trapped.png" }, node.param2, false, + "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_small") mesecon.receptor_on(pos, trapped_chest_mesecons_rules) end, function(pos, node, clicker) local meta = minetest.get_meta(pos) meta:set_int("players", 1) - minetest.swap_node(pos, {name="mcl_chests:trapped_chest_on_left", param2 = node.param2}) - find_or_create_entity(pos, "mcl_chests:trapped_chest_on_left", tiles_chest_trapped_double, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left") + minetest.swap_node(pos, { name = "mcl_chests:trapped_chest_on_left", param2 = node.param2 }) + find_or_create_entity(pos, "mcl_chests:trapped_chest_on_left", tiles_chest_trapped_double, node.param2, true, + "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left") mesecon.receptor_on(pos, trapped_chest_mesecons_rules) local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left") - minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_on_right", param2 = node.param2}) + minetest.swap_node(pos_other, { name = "mcl_chests:trapped_chest_on_right", param2 = node.param2 }) mesecon.receptor_on(pos_other, trapped_chest_mesecons_rules) end, function(pos, node, clicker) local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right") - minetest.swap_node(pos, {name="mcl_chests:trapped_chest_on_right", param2 = node.param2}) + minetest.swap_node(pos, { name = "mcl_chests:trapped_chest_on_right", param2 = node.param2 }) mesecon.receptor_on(pos, trapped_chest_mesecons_rules) - minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_on_left", param2 = node.param2}) - find_or_create_entity(pos_other, "mcl_chests:trapped_chest_on_left", tiles_chest_trapped_double, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left") + minetest.swap_node(pos_other, { name = "mcl_chests:trapped_chest_on_left", param2 = node.param2 }) + find_or_create_entity(pos_other, "mcl_chests:trapped_chest_on_left", tiles_chest_trapped_double, node.param2, + true, + "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left") mesecon.receptor_on(pos_other, trapped_chest_mesecons_rules) end ) register_chest("trapped_chest_on", nil, nil, nil, nil, traptiles, true, - {receptor = { - state = mesecon.state.on, - rules = trapped_chest_mesecons_rules, - }}, + { + receptor = { + state = mesecon.state.on, + rules = trapped_chest_mesecons_rules, + }, + }, nil, nil, nil, "trapped_chest", "trapped_chest" @@ -946,77 +1059,86 @@ end) minetest.register_craft({ output = "mcl_chests:chest", recipe = { - {"group:wood", "group:wood", "group:wood"}, - {"group:wood", "", "group:wood"}, - {"group:wood", "group:wood", "group:wood"}, - } + { "group:wood", "group:wood", "group:wood" }, + { "group:wood", "", "group:wood" }, + { "group:wood", "group:wood", "group:wood" }, + }, }) minetest.register_craft({ type = "fuel", recipe = "mcl_chests:chest", - burntime = 15 + burntime = 15, }) minetest.register_craft({ type = "fuel", recipe = "mcl_chests:trapped_chest", - burntime = 15 + burntime = 15, }) minetest.register_node("mcl_chests:ender_chest", { description = S("Ender Chest"), - _tt_help = S("27 interdimensional inventory slots") .. "\n" .. S("Put items inside, retrieve them from any ender chest"), - _doc_items_longdesc = S("Ender chests grant you access to a single personal interdimensional inventory with 27 slots. This inventory is the same no matter from which ender chest you access it from. If you put one item into one ender chest, you will find it in all other ender chests. Each player will only see their own items, but not the items of other players."), + _tt_help = S("27 interdimensional inventory slots") .. + "\n" .. S("Put items inside, retrieve them from any ender chest"), + _doc_items_longdesc = S( + "Ender chests grant you access to a single personal interdimensional inventory with 27 slots. This inventory is the same no matter from which ender chest you access it from. If you put one item into one ender chest, you will find it in all other ender chests. Each player will only see their own items, but not the items of other players."), _doc_items_usagehelp = S("Rightclick the ender chest to access your personal interdimensional inventory."), drawtype = "mesh", mesh = "mcl_chests_chest.b3d", tiles = tiles_chest_ender_small, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + use_texture_alpha = "opaque", paramtype = "light", paramtype2 = "facedir", - stack_max = 64, - groups = {deco_block=1}, + groups = { deco_block = 1 }, sounds = mcl_sounds.node_sound_stone_defaults(), - on_construct = function(pos, node) + on_construct = function(pos) local node = minetest.get_node(pos) node.name = "mcl_chests:ender_chest_small" minetest.set_node(pos, node) end, }) -local formspec_ender_chest = "size[9,8.75]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Ender Chest"))).."]".. - "list[current_player;enderchest;0,0.5;9,3;]".. - mcl_formspec.get_itemslot_bg(0,0.5,9,3).. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "listring[current_player;enderchest]".. - "listring[current_player;main]" +local formspec_ender_chest = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Ender Chest"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3), + "list[current_player;enderchest;0.375,0.75;9,3;]", + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + + "listring[current_player;enderchest]", + "listring[current_player;main]", +}) minetest.register_node("mcl_chests:ender_chest_small", { description = S("Ender Chest"), - _tt_help = S("27 interdimensional inventory slots") .. "\n" .. S("Put items inside, retrieve them from any ender chest"), - _doc_items_longdesc = S("Ender chests grant you access to a single personal interdimensional inventory with 27 slots. This inventory is the same no matter from which ender chest you access it from. If you put one item into one ender chest, you will find it in all other ender chests. Each player will only see their own items, but not the items of other players."), + _tt_help = S("27 interdimensional inventory slots") .. + "\n" .. S("Put items inside, retrieve them from any ender chest"), + _doc_items_longdesc = S( + "Ender chests grant you access to a single personal interdimensional inventory with 27 slots. This inventory is the same no matter from which ender chest you access it from. If you put one item into one ender chest, you will find it in all other ender chests. Each player will only see their own items, but not the items of other players."), _doc_items_usagehelp = S("Rightclick the ender chest to access your personal interdimensional inventory."), drawtype = "nodebox", node_box = { type = "fixed", - fixed = {-0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375}, + fixed = { -0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375 }, }, _chest_entity_textures = ender_chest_texture, _chest_entity_sound = "mcl_chests_enderchest", _chest_entity_mesh = "mcl_chests_chest", _chest_entity_animation_type = "chest", - tiles = {"blank.png^[resize:16x16"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + tiles = { "blank.png^[resize:16x16" }, + use_texture_alpha = "clip", -- Note: The “container” group is missing here because the ender chest does not -- have an inventory on its own - groups = {pickaxey=1, deco_block=1, material_stone=1, chest_entity=1, not_in_creative_inventory=1}, + groups = { pickaxey = 1, deco_block = 1, material_stone = 1, chest_entity = 1, not_in_creative_inventory = 1 }, is_ground_content = false, paramtype = "light", light_source = 7, @@ -1024,15 +1146,18 @@ minetest.register_node("mcl_chests:ender_chest_small", { sounds = mcl_sounds.node_sound_stone_defaults(), drop = "mcl_core:obsidian 8", on_construct = function(pos) - create_entity(pos, "mcl_chests:ender_chest_small", ender_chest_texture, minetest.get_node(pos).param2, false, "mcl_chests_enderchest", "mcl_chests_chest", "chest") + create_entity(pos, "mcl_chests:ender_chest_small", ender_chest_texture, minetest.get_node(pos).param2, false, + "mcl_chests_enderchest", "mcl_chests_chest", "chest") end, on_rightclick = function(pos, node, clicker) - if minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name].groups.opaque == 1 then - -- won't open if there is no space from the top - return false + if minetest.registered_nodes[minetest.get_node(vector.offset(pos, 0, 1, 0)).name].groups.opaque == 1 then + -- won't open if there is no space from the top + return false end - minetest.show_formspec(clicker:get_player_name(), "mcl_chests:ender_chest_"..clicker:get_player_name(), formspec_ender_chest) - player_chest_open(clicker, pos, "mcl_chests:ender_chest_small", ender_chest_texture, node.param2, false, "mcl_chests_enderchest", "mcl_chests_chest") + minetest.show_formspec(clicker:get_player_name(), "mcl_chests:ender_chest_" .. clicker:get_player_name(), + formspec_ender_chest) + player_chest_open(clicker, pos, "mcl_chests:ender_chest_small", ender_chest_texture, node.param2, false, + "mcl_chests_enderchest", "mcl_chests_chest") end, on_receive_fields = function(pos, formname, fields, sender) if fields.quit then @@ -1041,21 +1166,21 @@ minetest.register_node("mcl_chests:ender_chest_small", { end, _mcl_blast_resistance = 3000, _mcl_hardness = 22.5, - _mcl_silk_touch_drop = {"mcl_chests:ender_chest"}, + _mcl_silk_touch_drop = { "mcl_chests:ender_chest" }, on_rotate = simple_rotate, }) minetest.register_on_joinplayer(function(player) local inv = player:get_inventory() - inv:set_size("enderchest", 9*3) + inv:set_size("enderchest", 9 * 3) end) minetest.register_allow_player_inventory_action(function(player, action, inv, info) if inv:get_location().type == "player" and ( - action == "move" and (info.from_list == "enderchest" or info.to_list == "enderchest") - or action == "put" and info.listname == "enderchest" - or action == "take" and info.listname == "enderchest" - ) then + action == "move" and (info.from_list == "enderchest" or info.to_list == "enderchest") + or action == "put" and info.listname == "enderchest" + or action == "take" and info.listname == "enderchest" + ) then local def = player:get_wielded_item():get_definition() local range = (def and def.range or player:get_inventory():get_stack("hand", 1):get_definition().range) + 1 if not minetest.find_node_near(player:get_pos(), range, "mcl_chests:ender_chest_small", true) then @@ -1067,10 +1192,10 @@ end) minetest.register_craft({ output = "mcl_chests:ender_chest", recipe = { - {"mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian"}, - {"mcl_core:obsidian", "mcl_end:ender_eye", "mcl_core:obsidian"}, - {"mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian"}, - } + { "mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian" }, + { "mcl_core:obsidian", "mcl_end:ender_eye", "mcl_core:obsidian" }, + { "mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian" }, + }, }) -- Shulker boxes @@ -1113,21 +1238,29 @@ local shulker_mob_textures = { } local canonical_shulker_color = "violet" +--WARNING: after formspec v4 update, old shulker boxes will need to be placed again to get the new formspec local function formspec_shulker_box(name) - if name == "" then + if not name or name == "" then name = S("Shulker Box") end - return "size[9,8.75]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", name)).."]".. - "list[context;main;0,0.5;9,3;]".. - mcl_formspec.get_itemslot_bg(0,0.5,9,3).. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "listring[context;main]".. - "listring[current_player;main]" + + return table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, name)) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3), + "list[context;main;0.375,0.75;9,3;]", + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + + "listring[context;main]", + "listring[current_player;main]", + }) end local function set_shulkerbox_meta(nmeta, imeta) @@ -1143,28 +1276,38 @@ for color, desc in pairs(boxtypes) do local longdesc, usagehelp, create_entry, entry_name if mod_doc then if is_canonical then - longdesc = S("A shulker box is a portable container which provides 27 inventory slots for any item except shulker boxes. Shulker boxes keep their inventory when broken, so shulker boxes as well as their contents can be taken as a single item. Shulker boxes come in many different colors.") - usagehelp = S("To access the inventory of a shulker box, place and right-click it. To take a shulker box and its contents with you, just break and collect it, the items will not fall out. Place the shulker box again to be able to retrieve its contents.") + longdesc = S( + "A shulker box is a portable container which provides 27 inventory slots for any item except shulker boxes. Shulker boxes keep their inventory when broken, so shulker boxes as well as their contents can be taken as a single item. Shulker boxes come in many different colors.") + usagehelp = S( + "To access the inventory of a shulker box, place and right-click it. To take a shulker box and its contents with you, just break and collect it, the items will not fall out. Place the shulker box again to be able to retrieve its contents.") entry_name = S("Shulker Box") else create_entry = false end end - local small_name = "mcl_chests:"..color.."_shulker_box_small" + local small_name = "mcl_chests:" .. color .. "_shulker_box_small" - minetest.register_node("mcl_chests:"..color.."_shulker_box", { + minetest.register_node("mcl_chests:" .. color .. "_shulker_box", { description = desc, _tt_help = S("27 inventory slots") .. "\n" .. S("Can be carried around with its contents"), _doc_items_create_entry = create_entry, _doc_items_entry_name = entry_name, _doc_items_longdesc = longdesc, _doc_items_usagehelp = usagehelp, - tiles = {mob_texture}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + tiles = { mob_texture }, + use_texture_alpha = "opaque", drawtype = "mesh", mesh = "mcl_chests_shulker.b3d", - groups = {handy=1,pickaxey=1, container=3, deco_block=1, dig_by_piston=1, shulker_box=1, old_shulker_box_node=1}, + groups = { + handy = 1, + pickaxey = 1, + container = 3, + deco_block = 1, + dig_by_piston = 1, + shulker_box = 1, + old_shulker_box_node = 1 + }, is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(), stack_max = 1, @@ -1182,7 +1325,7 @@ for color, desc in pairs(boxtypes) do local iinv_main = minetest.deserialize(imetadata) local ninv = nmeta:get_inventory() ninv:set_list("main", iinv_main) - ninv:set_size("main", 9*3) + ninv:set_size("main", 9 * 3) set_shulkerbox_meta(nmeta, itemstack:get_meta()) if minetest.is_creative_enabled(placer:get_player_name()) then @@ -1198,12 +1341,12 @@ for color, desc in pairs(boxtypes) do _on_dispense = function(stack, pos, droppos, dropnode, dropdir) -- Place shulker box as node if minetest.registered_nodes[dropnode.name].buildable_to then - minetest.set_node(droppos, {name = small_name, param2 = minetest.dir_to_facedir(dropdir)}) - local ninv = minetest.get_inventory({type="node", pos=droppos}) + minetest.set_node(droppos, { name = small_name, param2 = minetest.dir_to_facedir(dropdir) }) + local ninv = minetest.get_inventory({ type = "node", pos = droppos }) local imetadata = stack:get_metadata() local iinv_main = minetest.deserialize(imetadata) ninv:set_list("main", iinv_main) - ninv:set_size("main", 9*3) + ninv:set_size("main", 9 * 3) set_shulkerbox_meta(minetest.get_meta(droppos), stack:get_meta()) stack:take_item() end @@ -1221,30 +1364,40 @@ for color, desc in pairs(boxtypes) do drawtype = "nodebox", node_box = { type = "fixed", - fixed = {-0.48, -0.5, -0.48, 0.48, 0.489, 0.48}, + fixed = { -0.48, -0.5, -0.48, 0.48, 0.489, 0.48 }, }, - tiles = {"blank.png^[resize:16x16"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, - _chest_entity_textures = {mob_texture}, + tiles = { "blank.png^[resize:16x16" }, + use_texture_alpha = "clip", + _chest_entity_textures = { mob_texture }, _chest_entity_sound = "mcl_chests_shulker", _chest_entity_mesh = "mcl_chests_shulker", _chest_entity_animation_type = "shulker", - groups = {handy=1,pickaxey=1, container=3, deco_block=1, dig_by_piston=1, shulker_box=1, chest_entity=1, not_in_creative_inventory=1}, + groups = { + handy = 1, + pickaxey = 1, + container = 3, + deco_block = 1, + dig_by_piston = 1, + shulker_box = 1, + chest_entity = 1, + not_in_creative_inventory = 1 + }, is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(), stack_max = 1, drop = "", paramtype = "light", paramtype2 = "facedir", --- TODO: Make shulker boxes rotatable --- This doesn't work, it just destroys the inventory: --- on_place = minetest.rotate_node, + -- TODO: Make shulker boxes rotatable + -- This doesn't work, it just destroys the inventory: + -- on_place = minetest.rotate_node, on_construct = function(pos) local meta = minetest.get_meta(pos) meta:set_string("formspec", formspec_shulker_box(nil)) local inv = meta:get_inventory() - inv:set_size("main", 9*3) - create_entity(pos, small_name, {mob_texture}, minetest.get_node(pos).param2, false, "mcl_chests_shulker", "mcl_chests_shulker", "shulker") + inv:set_size("main", 9 * 3) + create_entity(pos, small_name, { mob_texture }, minetest.get_node(pos).param2, false, "mcl_chests_shulker", + "mcl_chests_shulker", "shulker") end, after_place_node = function(pos, placer, itemstack, pointed_thing) local nmeta = minetest.get_meta(pos) @@ -1252,7 +1405,7 @@ for color, desc in pairs(boxtypes) do local iinv_main = minetest.deserialize(imetadata) local ninv = nmeta:get_inventory() ninv:set_list("main", iinv_main) - ninv:set_size("main", 9*3) + ninv:set_size("main", 9 * 3) set_shulkerbox_meta(nmeta, itemstack:get_meta()) if minetest.is_creative_enabled(placer:get_player_name()) then @@ -1266,7 +1419,8 @@ for color, desc in pairs(boxtypes) do end end, on_rightclick = function(pos, node, clicker) - player_chest_open(clicker, pos, small_name, {mob_texture}, node.param2, false, "mcl_chests_shulker", "mcl_chests_shulker", true) + player_chest_open(clicker, pos, small_name, { mob_texture }, node.param2, false, "mcl_chests_shulker", + "mcl_chests_shulker", true) end, on_receive_fields = function(pos, formname, fields, sender) if fields.quit then @@ -1277,12 +1431,12 @@ for color, desc in pairs(boxtypes) do local meta = minetest.get_meta(pos) local inv = meta:get_inventory() local items = {} - for i=1, inv:get_size("main") do + for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) items[i] = stack:to_string() end local data = minetest.serialize(items) - local boxitem = ItemStack("mcl_chests:"..color.."_shulker_box") + local boxitem = ItemStack("mcl_chests:" .. color .. "_shulker_box") local boxitem_meta = boxitem:get_meta() boxitem_meta:set_string("description", meta:get_string("description")) boxitem_meta:set_string("name", meta:get_string("name")) @@ -1317,24 +1471,26 @@ for color, desc in pairs(boxtypes) do }) if mod_doc and not is_canonical then - doc.add_entry_alias("nodes", "mcl_chests:"..canonical_shulker_color.."_shulker_box", "nodes", "mcl_chests:"..color.."_shulker_box") - doc.add_entry_alias("nodes", "mcl_chests:"..canonical_shulker_color.."_shulker_box_small", "nodes", "mcl_chests:"..color.."_shulker_box_small") + doc.add_entry_alias("nodes", "mcl_chests:" .. canonical_shulker_color .. "_shulker_box", "nodes", + "mcl_chests:" .. color .. "_shulker_box") + doc.add_entry_alias("nodes", "mcl_chests:" .. canonical_shulker_color .. "_shulker_box_small", "nodes", + "mcl_chests:" .. color .. "_shulker_box_small") end minetest.register_craft({ type = "shapeless", - output = "mcl_chests:"..color.."_shulker_box", - recipe = { "group:shulker_box", "mcl_dye:"..color } + output = "mcl_chests:" .. color .. "_shulker_box", + recipe = { "group:shulker_box", "mcl_dye:" .. color }, }) end minetest.register_craft({ output = "mcl_chests:violet_shulker_box", recipe = { - {"mcl_mobitems:shulker_shell"}, - {"mcl_chests:chest"}, - {"mcl_mobitems:shulker_shell"}, - } + { "mcl_mobitems:shulker_shell" }, + { "mcl_chests:chest" }, + { "mcl_mobitems:shulker_shell" }, + }, }) -- Save metadata of shulker box when used in crafting @@ -1362,13 +1518,14 @@ local function select_and_spawn_entity(pos, node) local node_name = node.name local node_def = minetest.registered_nodes[node_name] local double_chest = minetest.get_item_group(node_name, "double_chest") > 0 - find_or_create_entity(pos, node_name, node_def._chest_entity_textures, node.param2, double_chest, node_def._chest_entity_sound, node_def._chest_entity_mesh, node_def._chest_entity_animation_type) + find_or_create_entity(pos, node_name, node_def._chest_entity_textures, node.param2, double_chest, + node_def._chest_entity_sound, node_def._chest_entity_mesh, node_def._chest_entity_animation_type) end minetest.register_lbm({ label = "Spawn Chest entities", name = "mcl_chests:spawn_chest_entities", - nodenames = {"group:chest_entity"}, + nodenames = { "group:chest_entity" }, run_at_every_load = true, action = select_and_spawn_entity, }) @@ -1376,7 +1533,9 @@ minetest.register_lbm({ minetest.register_lbm({ label = "Replace old chest nodes", name = "mcl_chests:replace_old", - nodenames = {"mcl_chests:chest", "mcl_chests:trapped_chest", "mcl_chests:trapped_chest_on", "mcl_chests:ender_chest", "group:old_shulker_box_node"}, + nodenames = { "mcl_chests:chest", "mcl_chests:trapped_chest", "mcl_chests:trapped_chest_on", + "mcl_chests:ender_chest", + "group:old_shulker_box_node" }, run_at_every_load = true, action = function(pos, node) local node_name = node.name @@ -1384,7 +1543,7 @@ minetest.register_lbm({ minetest.swap_node(pos, node) select_and_spawn_entity(pos, node) if node_name == "mcl_chests:trapped_chest_on" then - minetest.log("action", "[mcl_chests] Disabled active trapped chest on load: " ..minetest.pos_to_string(pos)) + minetest.log("action", "[mcl_chests] Disabled active trapped chest on load: " .. minetest.pos_to_string(pos)) chest_update_after_close(pos) elseif node_name == "mcl_chests:ender_chest" then local meta = minetest.get_meta(pos) @@ -1399,29 +1558,30 @@ minetest.register_lbm({ -- Fixes redstone weirdness. label = "Disable active trapped chests", name = "mcl_chests:reset_trapped_chests", - nodenames = { "mcl_chests:trapped_chest_on_small", "mcl_chests:trapped_chest_on_left", "mcl_chests:trapped_chest_on_right" }, + nodenames = { "mcl_chests:trapped_chest_on_small", "mcl_chests:trapped_chest_on_left", + "mcl_chests:trapped_chest_on_right" }, run_at_every_load = true, action = function(pos, node) - minetest.log("action", "[mcl_chests] Disabled active trapped chest on load: " ..minetest.pos_to_string(pos)) + minetest.log("action", "[mcl_chests] Disabled active trapped chest on load: " .. minetest.pos_to_string(pos)) chest_update_after_close(pos) end, }) minetest.register_lbm({ - label = "Update shulker box formspecs (0.60.0)", - name = "mcl_chests:update_shulker_box_formspecs_0_60_0", + label = "Update shulker box formspecs (0.72.0)", + name = "mcl_chests:update_shulker_box_formspecs_0_72_0", nodenames = { "group:shulker_box" }, run_at_every_load = false, action = function(pos, node) local meta = minetest.get_meta(pos) - meta:set_string("formspec", formspec_shulker_box) + meta:set_string("formspec", formspec_shulker_box(meta:get_string("name"))) end, }) minetest.register_lbm({ label = "Upgrade old ender chest formspec", name = "mcl_chests:replace_old_ender_form", - nodenames = {"mcl_chests:ender_chest_small"}, + nodenames = { "mcl_chests:ender_chest_small" }, run_at_every_load = false, action = function(pos, node) minetest.get_meta(pos):set_string("formspec", "") diff --git a/mods/ITEMS/mcl_crafting_table/init.lua b/mods/ITEMS/mcl_crafting_table/init.lua index 7f6b9ccc5..2f114362d 100644 --- a/mods/ITEMS/mcl_crafting_table/init.lua +++ b/mods/ITEMS/mcl_crafting_table/init.lua @@ -1,34 +1,51 @@ +---@diagnostic disable lowercase-global + local S = minetest.get_translator(minetest.get_current_modname()) -local formspec_escape = minetest.formspec_escape -local show_formspec = minetest.show_formspec +local F = minetest.formspec_escape local C = minetest.colorize -local text_color = "#313131" -local itemslot_bg = mcl_formspec.get_itemslot_bg +local show_formspec = minetest.show_formspec mcl_crafting_table = {} -function mcl_crafting_table.show_crafting_form(player) - player:get_inventory():set_width("craft", 3) - player:get_inventory():set_size("craft", 9) +mcl_crafting_table.formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", - show_formspec(player:get_player_name(), "main", - "size[9,8.75]".. - "image[4.7,1.5;1.5,1;gui_crafting_arrow.png]".. - "label[0,4;"..formspec_escape(C(text_color, S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - itemslot_bg(0,7.74,9,1).. - "label[1.75,0;"..formspec_escape(C(text_color, S("Crafting"))).."]".. - "list[current_player;craft;1.75,0.5;3,3;]".. - itemslot_bg(1.75,0.5,3,3).. - "list[current_player;craftpreview;6.1,1.5;1,1;]".. - itemslot_bg(6.1,1.5,1,1).. - "image_button[0.75,1.5;1,1;craftguide_book.png;__mcl_craftguide;]".. - "tooltip[__mcl_craftguide;"..formspec_escape(S("Recipe book")).."]".. - "listring[current_player;main]".. - "listring[current_player;craft]" - ) + "label[2.25,0.375;" .. F(C(mcl_formspec.label_color, S("Crafting"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(2.25, 0.75, 3, 3), + "list[current_player;craft;2.25,0.75;3,3;]", + + "image[6.125,2;1.5,1;gui_crafting_arrow.png]", + + mcl_formspec.get_itemslot_bg_v4(8.2, 2, 1, 1, 0.2), + "list[current_player;craftpreview;8.2,2;1,1;]", + + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + + "listring[current_player;craft]", + "listring[current_player;main]", + + --Crafting guide button + "image_button[0.325,1.95;1.1,1.1;craftguide_book.png;__mcl_craftguide;]", + "tooltip[__mcl_craftguide;" .. F(S("Recipe book")) .. "]", +}) + +---@param player ObjectRef +function mcl_crafting_table.show_crafting_form(player) + local inv = player:get_inventory() + if inv then + inv:set_width("craft", 3) + inv:set_size("craft", 9) + end + + show_formspec(player:get_player_name(), "main", mcl_crafting_table.formspec) end minetest.register_node("mcl_crafting_table:crafting_table", { @@ -38,10 +55,10 @@ minetest.register_node("mcl_crafting_table:crafting_table", { _doc_items_usagehelp = S("Rightclick the crafting table to access the 3×3 crafting grid."), _doc_items_hidden = false, is_ground_content = false, - tiles = {"crafting_workbench_top.png", "default_wood.png", "crafting_workbench_side.png", - "crafting_workbench_side.png", "crafting_workbench_front.png", "crafting_workbench_front.png"}, + tiles = { "crafting_workbench_top.png", "default_wood.png", "crafting_workbench_side.png", + "crafting_workbench_side.png", "crafting_workbench_front.png", "crafting_workbench_front.png" }, paramtype2 = "facedir", - groups = {handy=1,axey=1, deco_block=1, material_wood=1,flammable=-1}, + groups = { handy = 1, axey = 1, deco_block = 1, material_wood = 1, flammable = -1 }, on_rightclick = function(pos, node, player, itemstack) if not player:get_player_control().sneak then mcl_crafting_table.show_crafting_form(player) @@ -55,9 +72,9 @@ minetest.register_node("mcl_crafting_table:crafting_table", { minetest.register_craft({ output = "mcl_crafting_table:crafting_table", recipe = { - {"group:wood", "group:wood"}, - {"group:wood", "group:wood"} - } + { "group:wood", "group:wood" }, + { "group:wood", "group:wood" } + }, }) minetest.register_craft({ diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index fa6dea353..b5766dd28 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -2,7 +2,8 @@ local S = minetest.get_translator(minetest.get_current_modname()) local F = minetest.formspec_escape function mcl_enchanting.is_book(itemname) - return itemname == "mcl_books:book" or itemname == "mcl_enchanting:book_enchanted" or itemname == "mcl_books:book_enchanted" + return itemname == "mcl_books:book" or itemname == "mcl_enchanting:book_enchanted" or + itemname == "mcl_books:book_enchanted" end function mcl_enchanting.get_enchantments(itemstack) @@ -54,11 +55,13 @@ end function mcl_enchanting.get_enchantment_description(enchantment, level) local enchantment_def = mcl_enchanting.enchantments[enchantment] - return enchantment_def.name .. (enchantment_def.max_level == 1 and "" or " " .. mcl_enchanting.roman_numerals.toRoman(level)) + return enchantment_def.name .. + (enchantment_def.max_level == 1 and "" or " " .. mcl_enchanting.roman_numerals.toRoman(level)) end function mcl_enchanting.get_colorized_enchantment_description(enchantment, level) - return minetest.colorize(mcl_enchanting.enchantments[enchantment].curse and mcl_colors.RED or mcl_colors.GRAY, mcl_enchanting.get_enchantment_description(enchantment, level)) + return minetest.colorize(mcl_enchanting.enchantments[enchantment].curse and mcl_colors.RED or mcl_colors.GRAY, + mcl_enchanting.get_enchantment_description(enchantment, level)) end function mcl_enchanting.get_enchanted_itemstring(itemname) @@ -79,7 +82,8 @@ function mcl_enchanting.not_enchantable_on_enchanting_table(itemname) end function mcl_enchanting.is_enchantable(itemname) - return mcl_enchanting.get_enchantability(itemname) > 0 or mcl_enchanting.not_enchantable_on_enchanting_table(itemname) + return mcl_enchanting.get_enchantability(itemname) > 0 or + mcl_enchanting.not_enchantable_on_enchanting_table(itemname) end function mcl_enchanting.can_enchant_freshly(itemname) @@ -150,7 +154,8 @@ function mcl_enchanting.can_enchant(itemstack, enchantment, level) for incompatible in pairs(enchantment_def.incompatible) do local incompatible_level = item_enchantments[incompatible] if incompatible_level then - return false, "incompatible", mcl_enchanting.get_enchantment_description(incompatible, incompatible_level) + return false, "incompatible", + mcl_enchanting.get_enchantment_description(incompatible, incompatible_level) end end end @@ -169,7 +174,9 @@ function mcl_enchanting.combine(itemstack, combine_with) local itemname = itemstack:get_name() local combine_name = combine_with:get_name() local enchanted_itemname = mcl_enchanting.get_enchanted_itemstring(itemname) - if not enchanted_itemname or enchanted_itemname ~= mcl_enchanting.get_enchanted_itemstring(combine_name) and not mcl_enchanting.is_book(combine_name) then + if not enchanted_itemname or + enchanted_itemname ~= mcl_enchanting.get_enchanted_itemstring(combine_name) and + not mcl_enchanting.is_book(combine_name) then return false end local enchantments = mcl_enchanting.get_enchantments(itemstack) @@ -219,7 +226,7 @@ function mcl_enchanting.enchantments_snippet(_, _, itemstack) local enchantments = mcl_enchanting.get_enchantments(itemstack) local text = "" for enchantment, level in pairs(enchantments) do - text = text .. mcl_enchanting.get_colorized_enchantment_description(enchantment, level) .. "\n" + text = text .. mcl_enchanting.get_colorized_enchantment_description(enchantment, level) .. "\n" end if text ~= "" then if not itemstack:get_definition()._tt_original_description then @@ -267,7 +274,7 @@ function mcl_enchanting.initialize() for itemname, itemdef in pairs(minetest.registered_items) do if mcl_enchanting.can_enchant_freshly(itemname) and not mcl_enchanting.is_book(itemname) then local new_name = itemname .. "_enchanted" - minetest.override_item(itemname, {_mcl_enchanting_enchanted_tool = new_name}) + minetest.override_item(itemname, { _mcl_enchanting_enchanted_tool = new_name }) local new_def = table.copy(itemdef) new_def.inventory_image = itemdef.inventory_image .. mcl_enchanting.overlay if new_def.wield_image then @@ -303,7 +310,7 @@ end function mcl_enchanting.random(pr, ...) local r = pr and pr:next(...) or math.random(...) - if pr and not ({...})[1] then + if pr and not ({ ... })[1] then r = r / 32767 end @@ -328,20 +335,24 @@ function mcl_enchanting.get_random_enchantment(itemstack, treasure, weighted, ex return #possible > 0 and possible[mcl_enchanting.random(pr, 1, #possible)] end -function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) +function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, + ignore_already_enchanted, pr) local itemname = itemstack:get_name() - if (not mcl_enchanting.can_enchant_freshly(itemname) and not ignore_already_enchanted) or mcl_enchanting.not_enchantable_on_enchanting_table(itemname) then + if (not mcl_enchanting.can_enchant_freshly(itemname) and not ignore_already_enchanted) or + mcl_enchanting.not_enchantable_on_enchanting_table(itemname) then return end itemstack = ItemStack(itemstack) local enchantability = minetest.get_item_group(itemname, "enchantability") - enchantability = 1 + mcl_enchanting.random(pr, 0, math.floor(enchantability / 4)) + mcl_enchanting.random(pr, 0, math.floor(enchantability / 4)) + enchantability = 1 + mcl_enchanting.random(pr, 0, math.floor(enchantability / 4)) + + mcl_enchanting.random(pr, 0, math.floor(enchantability / 4)) enchantment_level = enchantment_level + enchantability - enchantment_level = enchantment_level + enchantment_level * (mcl_enchanting.random(pr) + mcl_enchanting.random(pr) - 1) * 0.15 + enchantment_level = enchantment_level + + enchantment_level * (mcl_enchanting.random(pr) + mcl_enchanting.random(pr) - 1) * 0.15 enchantment_level = math.max(math.floor(enchantment_level + 0.5), 1) local enchantments = {} @@ -387,7 +398,6 @@ function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_leve enchantments[selected_enchantment] = enchantment_power mcl_enchanting.enchant(itemstack, selected_enchantment, enchantment_power) end - until not no_reduced_bonus_chance and mcl_enchanting.random(pr) >= (enchantment_level + 1) / 50 return enchantments, description @@ -397,13 +407,15 @@ function mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchant local enchantments repeat - enchantments = mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) + enchantments = mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, + no_reduced_bonus_chance, ignore_already_enchanted, pr) until enchantments return enchantments end -function mcl_enchanting.enchant_randomly(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) +function mcl_enchanting.enchant_randomly(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, + ignore_already_enchanted, pr) local enchantments = mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) mcl_enchanting.set_enchanted_itemstring(itemstack) @@ -416,7 +428,8 @@ function mcl_enchanting.enchant_uniform_randomly(stack, exclude, pr) local enchantment = mcl_enchanting.get_random_enchantment(stack, true, false, exclude, pr) if enchantment then - mcl_enchanting.enchant(stack, enchantment, mcl_enchanting.random(pr, 1, mcl_enchanting.enchantments[enchantment].max_level)) + mcl_enchanting.enchant(stack, enchantment, + mcl_enchanting.random(pr, 1, mcl_enchanting.enchantments[enchantment].max_level)) end return stack @@ -426,7 +439,8 @@ function mcl_enchanting.get_random_glyph_row() local glyphs = "" local x = 1.3 for i = 1, 9 do - glyphs = glyphs .. "image[".. x .. ",0.1;0.5,0.5;mcl_enchanting_glyph_" .. math.random(18) .. ".png^[colorize:#675D49:255]" + glyphs = glyphs .. + "image[" .. x .. ",0.1;0.5,0.5;mcl_enchanting_glyph_" .. math.random(18) .. ".png^[colorize:#675D49:255]" x = x + 0.6 end return glyphs @@ -459,7 +473,7 @@ end function mcl_enchanting.get_table_slots(player, itemstack, num_bookshelves) local itemname = itemstack:get_name() if (not mcl_enchanting.can_enchant_freshly(itemname)) or mcl_enchanting.not_enchantable_on_enchanting_table(itemname) then - return {false, false, false} + return { false, false, false } end local meta = player:get_meta() local player_slots = minetest.deserialize(meta:get_string("mcl_enchanting:slots")) or {} @@ -475,7 +489,7 @@ function mcl_enchanting.get_table_slots(player, itemstack, num_bookshelves) meta:set_string("mcl_enchanting:slots", minetest.serialize(player_slots)) return player_bookshelves_item_slots else - return {false, false, false} + return { false, false, false } end end end @@ -491,28 +505,33 @@ function mcl_enchanting.show_enchanting_formspec(player) local inv = player:get_inventory() local num_bookshelves = meta:get_int("mcl_enchanting:num_bookshelves") local table_name = meta:get_string("mcl_enchanting:table_name") - local formspec = "" - .. "size[9.07,8.6;]" - .. "formspec_version[3]" - .. "label[0,0;" .. C("#313131") .. F(table_name) .. "]" - .. mcl_formspec.get_itemslot_bg(0.2, 2.4, 1, 1) - .. "list[current_player;enchanting_item;0.2,2.4;1,1]" - .. mcl_formspec.get_itemslot_bg(1.1, 2.4, 1, 1) - .. "image[1.1,2.4;1,1;mcl_enchanting_lapis_background.png]" - .. "list[current_player;enchanting_lapis;1.1,2.4;1,1]" - .. "label[0,4;" .. C("#313131") .. F(S("Inventory")).."]" - .. mcl_formspec.get_itemslot_bg(0, 4.5, 9, 3) - .. mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1) - .. "list[current_player;main;0,4.5;9,3;9]" - .. "listring[current_player;enchanting_item]" - .. "listring[current_player;main]" - .. "listring[current_player;enchanting]" - .. "listring[current_player;main]" - .. "listring[current_player;enchanting_lapis]" - .. "listring[current_player;main]" - .. "list[current_player;main;0,7.74;9,1;]" - .. "real_coordinates[true]" - .. "image[3.15,0.6;7.6,4.1;mcl_enchanting_button_background.png]" + + local formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color) .. table_name) .. "]", + mcl_formspec.get_itemslot_bg_v4(1, 3.25, 1, 1), + "list[current_player;enchanting_item;1,3.25;1,1]", + mcl_formspec.get_itemslot_bg_v4(2.25, 3.25, 1, 1), + "image[2.25,3.25;1,1;mcl_enchanting_lapis_background.png]", + "list[current_player;enchanting_lapis;2.25,3.25;1,1]", + "image[4.125,0.56;7.25,4.1;mcl_enchanting_button_background.png]", + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color) .. S("Inventory")) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + + "listring[current_player;enchanting_item]", + "listring[current_player;main]", + "listring[current_player;enchanting]", + "listring[current_player;main]", + "listring[current_player;enchanting_lapis]", + "listring[current_player;main]", + }) + local itemstack = inv:get_stack("enchanting_item", 1) local player_levels = mcl_experience.get_level(player) local y = 0.65 @@ -520,24 +539,50 @@ function mcl_enchanting.show_enchanting_formspec(player) local table_slots = mcl_enchanting.get_table_slots(player, itemstack, num_bookshelves) for i, slot in ipairs(table_slots) do any_enchantment = any_enchantment or slot - local enough_lapis = inv:contains_item("enchanting_lapis", ItemStack({name = "mcl_core:lapis", count = i})) + local enough_lapis = inv:contains_item("enchanting_lapis", ItemStack({ name = "mcl_core:lapis", count = i })) local enough_levels = slot and slot.level_requirement <= player_levels local can_enchant = (slot and enough_lapis and enough_levels) local ending = (can_enchant and "" or "_off") local hover_ending = (can_enchant and "_hovered" or "_off") formspec = formspec - .. "container[3.2," .. y .. "]" - .. (slot and "tooltip[button_" .. i .. ";" .. C("#818181") .. ((slot.description and F(slot.description)) or "") .. " " .. C("#FFFFFF") .. " . . . ?\n\n" .. (enough_levels and C(enough_lapis and "#818181" or "#FC5454") .. F(S("@1 Lapis Lazuli", i)) .. "\n" .. C("#818181") .. F(S("@1 Enchantment Levels", i)) or C("#FC5454") .. F(S("Level requirement: @1", slot.level_requirement))) .. "]" or "") - .. "style[button_" .. i .. ";bgimg=mcl_enchanting_button" .. ending .. ".png;bgimg_hovered=mcl_enchanting_button" .. hover_ending .. ".png;bgimg_pressed=mcl_enchanting_button" .. hover_ending .. ".png]" - .. "button[0,0;7.5,1.3;button_" .. i .. ";]" + .. "container[4.125," .. y .. "]" + .. + ( + slot and + "tooltip[button_" .. + i .. + ";" .. + C("#818181") .. + ((slot.description and F(slot.description)) or "") .. + " " .. + C("#FFFFFF") .. + " . . . ?\n\n" .. + ( + enough_levels and + C(enough_lapis and "#818181" or "#FC5454") .. + F(S("@1 Lapis Lazuli", i)) .. "\n" .. C("#818181") .. F(S("@1 Enchantment Levels", i)) or + C("#FC5454") .. F(S("Level requirement: @1", slot.level_requirement))) .. "]" or "") + .. + "style[button_" .. + i .. + ";bgimg=mcl_enchanting_button" .. + ending .. + ".png;bgimg_hovered=mcl_enchanting_button" .. + hover_ending .. ".png;bgimg_pressed=mcl_enchanting_button" .. hover_ending .. ".png]" + .. "button[0,0;7.25,1.3;button_" .. i .. ";]" .. (slot and "image[0,0;1.3,1.3;mcl_enchanting_number_" .. i .. ending .. ".png]" or "") - .. (slot and "label[7.2,1.1;" .. C(can_enchant and "#80FF20" or "#407F10") .. slot.level_requirement .. "]" or "") + .. (slot and "label[6.8,1;" .. C(can_enchant and "#80FF20" or "#407F10") .. slot.level_requirement .. "]" or "") .. (slot and slot.glyphs or "") .. "container_end[]" - y = y + 1.35 + y = y + 1.3 end formspec = formspec - .. "image[" .. (any_enchantment and 0.58 or 1.15) .. ",1.2;" .. (any_enchantment and 2 or 0.87) .. ",1.43;mcl_enchanting_book_" .. (any_enchantment and "open" or "closed") .. ".png]" + .. + "image[" .. + (any_enchantment and 1.1 or 1.67) .. + ",1.2;" .. + (any_enchantment and 2 or 0.87) .. + ",1.43;mcl_enchanting_book_" .. (any_enchantment and "open" or "closed") .. ".png]" minetest.show_formspec(name, "mcl_enchanting:table", formspec) end @@ -555,7 +600,7 @@ function mcl_enchanting.handle_formspec_fields(player, formname, fields) local meta = player:get_meta() local num_bookshelfes = meta:get_int("mcl_enchanting:num_bookshelves") local itemstack = inv:get_stack("enchanting_item", 1) - local cost = ItemStack({name = "mcl_core:lapis", count = button_pressed}) + local cost = ItemStack({ name = "mcl_core:lapis", count = button_pressed }) if not inv:contains_item("enchanting_lapis", cost) then return end @@ -573,7 +618,7 @@ function mcl_enchanting.handle_formspec_fields(player, formname, fields) mcl_enchanting.set_enchanted_itemstring(itemstack) mcl_enchanting.set_enchantments(itemstack, slot.enchantments) inv:set_stack("enchanting_item", 1, itemstack) - minetest.sound_play("mcl_enchanting_enchant", {to_player = name, gain = 5.0}) + minetest.sound_play("mcl_enchanting_enchant", { to_player = name, gain = 5.0 }) mcl_enchanting.reset_table_slots(player) mcl_enchanting.show_enchanting_formspec(player) awards.unlock(player:get_player_name(), "mcl:enchanter") @@ -603,7 +648,8 @@ function mcl_enchanting.is_enchanting_inventory_action(action, inventory, invent end function mcl_enchanting.allow_inventory_action(player, action, inventory, inventory_info) - local is_enchanting_action, do_limit = mcl_enchanting.is_enchanting_inventory_action(action, inventory, inventory_info) + local is_enchanting_action, do_limit = mcl_enchanting.is_enchanting_inventory_action(action, inventory, + inventory_info) if is_enchanting_action and do_limit then if action == "move" then local listname = inventory_info.to_list @@ -645,13 +691,15 @@ function mcl_enchanting.on_inventory_action(player, action, inventory, inventory end function mcl_enchanting.schedule_book_animation(self, anim) - self.scheduled_anim = {timer = self.anim_length, anim = anim} + self.scheduled_anim = { timer = self.anim_length, anim = anim } end function mcl_enchanting.set_book_animation(self, anim) local anim_index = mcl_enchanting.book_animations[anim] - local start, stop = mcl_enchanting.book_animation_steps[anim_index], mcl_enchanting.book_animation_steps[anim_index + 1] - self.object:set_animation({x = start, y = stop}, mcl_enchanting.book_animation_speed, 0, mcl_enchanting.book_animation_loop[anim] or false) + local start, stop = mcl_enchanting.book_animation_steps[anim_index], + mcl_enchanting.book_animation_steps[anim_index + 1] + self.object:set_animation({ x = start, y = stop }, mcl_enchanting.book_animation_speed, 0, + mcl_enchanting.book_animation_loop[anim] or false) self.scheduled_anim = nil self.anim_length = (stop - start) / 40 end @@ -661,7 +709,7 @@ function mcl_enchanting.check_animation_schedule(self, dtime) if schedanim then schedanim.timer = schedanim.timer - dtime if schedanim.timer <= 0 then - mcl_enchanting.set_book_animation(self, schedanim.anim) + mcl_enchanting.set_book_animation(self, schedanim.anim) end end end @@ -669,7 +717,7 @@ end function mcl_enchanting.look_at(self, pos2) local pos1 = self.object:get_pos() local vec = vector.subtract(pos1, pos2) - local yaw = math.atan(vec.z / vec.x) - math.pi/2 + local yaw = math.atan(vec.z / vec.x) - math.pi / 2 yaw = yaw + (pos1.x >= pos2.x and math.pi or 0) self.object:set_yaw(yaw + math.pi) end diff --git a/mods/ITEMS/mcl_furnaces/init.lua b/mods/ITEMS/mcl_furnaces/init.lua index 8cb8ad5a0..9cb8ffb16 100644 --- a/mods/ITEMS/mcl_furnaces/init.lua +++ b/mods/ITEMS/mcl_furnaces/init.lua @@ -1,5 +1,6 @@ - local S = minetest.get_translator(minetest.get_current_modname()) +local C = minetest.colorize +local F = minetest.formspec_escape local LIGHT_ACTIVE_FURNACE = 13 @@ -8,60 +9,82 @@ local LIGHT_ACTIVE_FURNACE = 13 -- local function active_formspec(fuel_percent, item_percent) - return "size[9,8.75]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Furnace"))).."]".. - "list[context;src;2.75,0.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. - "list[context;fuel;2.75,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,2.5,1,1).. - "list[context;dst;5.75,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(5.75,1.5,1,1).. - "image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:".. - (100-fuel_percent)..":default_furnace_fire_fg.png]".. - "image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[lowpart:".. - (item_percent)..":gui_furnace_arrow_fg.png^[transformR270]".. - -- Craft guide button temporarily removed due to Minetest bug. - -- TODO: Add it back when the Minetest bug is fixed. - --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. - --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. - "listring[context;dst]".. - "listring[current_player;main]".. - "listring[context;src]".. - "listring[current_player;main]".. - "listring[context;fuel]".. - "listring[current_player;main]" + return table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Furnace"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(3.5, 0.75, 1, 1), + "list[context;src;3.5,0.75;1,1;]", + + "image[3.5,2;1,1;default_furnace_fire_bg.png^[lowpart:" .. + (100 - fuel_percent) .. ":default_furnace_fire_fg.png]", + + mcl_formspec.get_itemslot_bg_v4(3.5, 3.25, 1, 1), + "list[context;fuel;3.5,3.25;1,1;]", + + "image[5.25,2;1.5,1;gui_furnace_arrow_bg.png^[lowpart:" .. + (item_percent) .. ":gui_furnace_arrow_fg.png^[transformR270]", + mcl_formspec.get_itemslot_bg_v4(7.875, 2, 1, 1, 0.2), + "list[context;dst;7.875,2;1,1;]", + + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + + -- Craft guide button temporarily removed due to Minetest bug. + -- TODO: Add it back when the Minetest bug is fixed. + --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. + --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. + + "listring[context;dst]", + "listring[current_player;main]", + "listring[context;src]", + "listring[current_player;main]", + "listring[context;fuel]", + "listring[current_player;main]", + }) end -local inactive_formspec = "size[9,8.75]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Furnace"))).."]".. - "list[context;src;2.75,0.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. - "list[context;fuel;2.75,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,2.5,1,1).. - "list[context;dst;5.75,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(5.75,1.5,1,1).. - "image[2.75,1.5;1,1;default_furnace_fire_bg.png]".. - "image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[transformR270]".. +local inactive_formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Furnace"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(3.5, 0.75, 1, 1), + "list[context;src;3.5,0.75;1,1;]", + + "image[3.5,2;1,1;default_furnace_fire_bg.png]", + + mcl_formspec.get_itemslot_bg_v4(3.5, 3.25, 1, 1), + "list[context;fuel;3.5,3.25;1,1;]", + + "image[5.25,2;1.5,1;gui_furnace_arrow_bg.png^[transformR270]", + + mcl_formspec.get_itemslot_bg_v4(7.875, 2, 1, 1, 0.2), + "list[context;dst;7.875,2;1,1;]", + + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + -- Craft guide button temporarily removed due to Minetest bug. -- TODO: Add it back when the Minetest bug is fixed. --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. - "listring[context;dst]".. - "listring[current_player;main]".. - "listring[context;src]".. - "listring[current_player;main]".. - "listring[context;fuel]".. - "listring[current_player;main]" + + "listring[context;dst]", + "listring[current_player;main]", + "listring[context;src]", + "listring[current_player;main]", + "listring[context;fuel]", + "listring[current_player;main]", +}) + local receive_fields = function(pos, formname, fields, sender) if fields.craftguide then @@ -71,7 +94,7 @@ end local function give_xp(pos, player) local meta = minetest.get_meta(pos) - local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2),-1.95) + local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2), -1.95) local xp = meta:get_int("xp") if xp > 0 then if player then @@ -108,7 +131,7 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player) -- Test stack with size 1 because we burn one fuel at a time local teststack = ItemStack(stack) teststack:set_count(1) - local output, decremented_input = minetest.get_craft_result({method="fuel", width=1, items={teststack}}) + local output, decremented_input = minetest.get_craft_result({ method = "fuel", width = 1, items = { teststack } }) if output.time ~= 0 then -- Only allow to place 1 item if fuel get replaced by recipe. -- This is the case for lava buckets. @@ -303,7 +326,7 @@ local function furnace_node_timer(pos, elapsed) -- Check if we have cookable content: cookable local aftercooked - cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) + cooked, aftercooked = minetest.get_craft_result({ method = "cooking", width = 1, items = srclist }) cookable = cooked.time ~= 0 if cookable then -- Successful cooking requires space in dst slot and time @@ -321,7 +344,7 @@ local function furnace_node_timer(pos, elapsed) if cookable and not active then -- We need to get new fuel local afterfuel - fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) + fuel, afterfuel = minetest.get_craft_result({ method = "fuel", width = 1, items = fuellist }) if fuel.time == 0 then -- No valid fuel in fuel list -- stop @@ -356,7 +379,7 @@ local function furnace_node_timer(pos, elapsed) if srclist[1]:get_name() == "mcl_sponges:sponge_wet" then inv:set_stack("fuel", 1, "mcl_buckets:bucket_water") fuellist = inv:get_list("fuel") - -- Also for river water + -- Also for river water elseif srclist[1]:get_name() == "mcl_sponges:sponge_wet_river_water" then inv:set_stack("fuel", 1, "mcl_buckets:bucket_river_water") fuellist = inv:get_list("fuel") @@ -366,7 +389,7 @@ local function furnace_node_timer(pos, elapsed) srclist = inv:get_list("src") src_time = 0 - meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count + meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count end end @@ -413,9 +436,9 @@ local function furnace_node_timer(pos, elapsed) meta:set_float("fuel_time", fuel_time) meta:set_float("src_time", src_time) if srclist then - meta:set_string("src_item", src_item) + meta:set_string("src_item", src_item) else - meta:set_string("src_item", "") + meta:set_string("src_item", "") end meta:set_string("formspec", formspec) @@ -440,11 +463,11 @@ minetest.register_node("mcl_furnaces:furnace", { _tt_help = S("Uses fuel to smelt or cook items"), _doc_items_longdesc = S("Furnaces cook or smelt several items, using a furnace fuel, into something else."), _doc_items_usagehelp = - S("Use the furnace to open the furnace menu.").."\n".. - S("Place a furnace fuel in the lower slot and the source material in the upper slot.").."\n".. - S("The furnace will slowly use its fuel to smelt the item.").."\n".. - S("The result will be placed into the output slot at the right side.").."\n".. - S("Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn."), + S("Use the furnace to open the furnace menu.") .. "\n" .. + S("Place a furnace fuel in the lower slot and the source material in the upper slot.") .. "\n" .. + S("The furnace will slowly use its fuel to smelt the item.") .. "\n" .. + S("The result will be placed into the output slot at the right side.") .. "\n" .. + S("Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn."), _doc_items_hidden = false, tiles = { "default_furnace_top.png", "default_furnace_bottom.png", @@ -452,7 +475,7 @@ minetest.register_node("mcl_furnaces:furnace", { "default_furnace_side.png", "default_furnace_front.png" }, paramtype2 = "facedir", - groups = {pickaxey=1, container=4, deco_block=1, material_stone=1}, + groups = { pickaxey = 1, container = 4, deco_block = 1, material_stone = 1 }, is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(), @@ -462,10 +485,11 @@ minetest.register_node("mcl_furnaces:furnace", { local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() - for _, listname in ipairs({"src", "dst", "fuel"}) do + for _, listname in ipairs({ "src", "dst", "fuel" }) do local stack = inv:get_stack(listname, 1) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = { x = pos.x + math.random(0, 10) / 10 - 0.5, y = pos.y, + z = pos.z + math.random(0, 10) / 10 - 0.5 } minetest.add_item(p, stack) end end @@ -528,7 +552,7 @@ minetest.register_node("mcl_furnaces:furnace_active", { paramtype = "light", light_source = LIGHT_ACTIVE_FURNACE, drop = "mcl_furnaces:furnace", - groups = {pickaxey=1, container=4, deco_block=1, not_in_creative_inventory=1, material_stone=1}, + groups = { pickaxey = 1, container = 4, deco_block = 1, not_in_creative_inventory = 1, material_stone = 1 }, is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(), on_timer = furnace_node_timer, @@ -538,10 +562,11 @@ minetest.register_node("mcl_furnaces:furnace_active", { local meta2 = meta meta:from_table(oldmetadata) local inv = meta:get_inventory() - for _, listname in ipairs({"src", "dst", "fuel"}) do + for _, listname in ipairs({ "src", "dst", "fuel" }) do local stack = inv:get_stack(listname, 1) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = { x = pos.x + math.random(0, 10) / 10 - 0.5, y = pos.y, + z = pos.z + math.random(0, 10) / 10 - 0.5 } minetest.add_item(p, stack) end end @@ -573,7 +598,7 @@ minetest.register_craft({ output = "mcl_furnaces:furnace", recipe = { { "group:cobble", "group:cobble", "group:cobble" }, - { "group:cobble", "", "group:cobble" }, + { "group:cobble", "", "group:cobble" }, { "group:cobble", "group:cobble", "group:cobble" }, } }) @@ -586,7 +611,7 @@ end minetest.register_lbm({ label = "Active furnace flame particles", name = "mcl_furnaces:flames", - nodenames = {"mcl_furnaces:furnace_active"}, + nodenames = { "mcl_furnaces:furnace_active" }, run_at_every_load = true, action = function(pos, node) spawn_flames(pos, node.param2) diff --git a/mods/ITEMS/mcl_grindstone/init.lua b/mods/ITEMS/mcl_grindstone/init.lua index 00c373536..e0137dcd1 100644 --- a/mods/ITEMS/mcl_grindstone/init.lua +++ b/mods/ITEMS/mcl_grindstone/init.lua @@ -1,37 +1,52 @@ -- Code based from mcl_anvils local S = minetest.get_translator(minetest.get_current_modname()) +local F = minetest.formspec_escape +local C = minetest.colorize local MAX_WEAR = 65535 --- formspecs -local function get_grindstone_formspec() - return "size[9,8.75]".. - "image[3,1.5;1.5,1;gui_crafting_arrow.png]".. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "label[1,0.1;"..minetest.formspec_escape(minetest.colorize("#313131", S("Repair & Disenchant"))).."]".. - "list[context;main;0,0;8,4;]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "list[context;input;1,1;1,1;]".. - mcl_formspec.get_itemslot_bg(1,1,1,1).. - "list[context;input;1,2;1,1;1]".. - mcl_formspec.get_itemslot_bg(1,2,1,1).. - "list[context;output;6,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(6,1.5,1,1).. - "listring[context;output]".. - "listring[current_player;main]".. - "listring[context;input]".. - "listring[current_player;main]" -end +local grindstone_formspec = table.concat({ + "formspec_version[6]", + "size[11.75,10.425]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Repair & Disenchant"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(2.875, 1.25, 1, 1), + "list[context;input;2.875,1.25;1,1;]", + + mcl_formspec.get_itemslot_bg_v4(2.875, 2.625, 1, 1), + "list[context;input;2.875,2.625;1,1;1]", + + "image[2.375,1;2,2.875;grindstone_gui_9.png;2]", + + "image[1.875,1.5;0.5,2.875;grindstone_gui_9.png;2]", + "image[4.375,1.5;0.5,2.875;grindstone_gui_9.png;2]", + + "image[5.5,1.95;1.5,1;gui_crafting_arrow.png]", + + mcl_formspec.get_itemslot_bg_v4(7.875, 1.9375, 1, 1), + "list[context;output;7.875,1.9375;1,1;]", + + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + + "listring[context;output]", + "listring[current_player;main]", + "listring[context;input]", + "listring[current_player;main]", +}) -- Creates a new item with the wear of the items and custom name local function create_new_item(name_item, meta, wear) local new_item = ItemStack(name_item) if wear ~= nil then - new_item:set_wear(wear) + new_item:set_wear(wear) end local new_meta = new_item:get_meta() new_meta:set_string("name", meta:get_string("name")) @@ -86,7 +101,6 @@ local function fix_stack_size(stack) return count end - -- Update the inventory slots of an grindstone node. -- meta: Metadata of grindstone node local function update_grindstone_slots(meta) @@ -122,8 +136,8 @@ local function update_grindstone_slots(meta) else new_output = "" end - -- Check if at least one input has an item - -- Check if the item is's an enchanted book or tool + -- Check if at least one input has an item + -- Check if the item is's an enchanted book or tool elseif (not input1:is_empty() and input2:is_empty()) or (input1:is_empty() and not input2:is_empty()) then if input2:is_empty() then local def1 = input1:get_definition() @@ -168,10 +182,10 @@ end -- Drop any items inside the grindstone if destroyed local function drop_grindstone_items(pos, meta) local inv = meta:get_inventory() - for i=1, inv:get_size("input") do + for i = 1, inv:get_size("input") do local stack = inv:get_stack("input", i) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = { x = pos.x + math.random(0, 10) / 10 - 0.5, y = pos.y, z = pos.z + math.random(0, 10) / 10 - 0.5 } minetest.add_item(p, stack) end end @@ -181,11 +195,11 @@ local node_box = { type = "fixed", -- created with nodebox editor fixed = { - {-0.25, -0.25, -0.375, 0.25, 0.5, 0.375}, - {-0.375, -0.0625, -0.1875, -0.25, 0.3125, 0.1875}, - {0.25, -0.0625, -0.1875, 0.375, 0.3125, 0.1875}, - {0.25, -0.5, -0.125, 0.375, -0.0625, 0.125}, - {-0.375, -0.5, -0.125, -0.25, -0.0625, 0.125}, + { -0.25, -0.25, -0.375, 0.25, 0.5, 0.375 }, + { -0.375, -0.0625, -0.1875, -0.25, 0.3125, 0.1875 }, + { 0.25, -0.0625, -0.1875, 0.375, 0.3125, 0.1875 }, + { 0.25, -0.5, -0.125, 0.375, -0.0625, 0.125 }, + { -0.375, -0.5, -0.125, -0.25, -0.0625, 0.125 }, } } @@ -193,11 +207,11 @@ minetest.register_node("mcl_grindstone:grindstone", { description = S("Grindstone"), _tt_help = S("Used to disenchant/fix tools"), _doc_items_longdesc = S("Grindstone disenchants tools and armour except for curses, and repairs two items of the same type it is also the weapon smith's work station."), - _doc_items_usagehelp = S("To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.").."\n".. - S("To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.").."\n".. - S("To repair a tool you need a tool of the same type and material, put both items in the input slot and the output slot will combine two items durabilities with 5% bonus.").."\n".. - S("If both items have enchantments the player will get xp from both items from the disenchant.").."\n".. - S("Curses cannot be removed and will be transfered to the new repaired item, if both items have a different curse the curses will be combined."), + _doc_items_usagehelp = S("To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.") .. "\n" .. + S("To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.") .. "\n" .. + S("To repair a tool you need a tool of the same type and material, put both items in the input slot and the output slot will combine two items durabilities with 5% bonus.") .. "\n" .. + S("If both items have enchantments the player will get xp from both items from the disenchant.") .. "\n" .. + S("Curses cannot be removed and will be transfered to the new repaired item, if both items have a different curse the curses will be combined."), tiles = { "grindstone_top.png", "grindstone_top.png", @@ -212,7 +226,7 @@ minetest.register_node("mcl_grindstone:grindstone", { selection_box = node_box, collision_box = node_box, sounds = mcl_sounds.node_sound_stone_defaults(), - groups = {pickaxey = 1, deco_block = 1}, + groups = { pickaxey = 1, deco_block = 1 }, after_dig_node = function(pos, oldnode, oldmetadata, digger) local meta = minetest.get_meta(pos) @@ -268,7 +282,7 @@ minetest.register_node("mcl_grindstone:grindstone", { local meta = minetest.get_meta(pos) if from_list == "output" and to_list == "input" then local inv = meta:get_inventory() - for i=1, inv:get_size("input") do + for i = 1, inv:get_size("input") do if i ~= to_index then local istack = inv:get_stack("input", i) istack:set_count(math.max(0, istack:get_count() - count)) @@ -289,8 +303,8 @@ minetest.register_node("mcl_grindstone:grindstone", { if not input1:is_empty() and not input2:is_empty() then -- Get xp earnt from the enchanted items xp_earnt = calculate_xp(input1) + calculate_xp(input1) - input1:take_item() - input2:take_item() + input1:take_item(1) + input2:take_item(1) inv:set_stack("input", 1, input1) inv:set_stack("input", 2, input2) else @@ -320,14 +334,13 @@ minetest.register_node("mcl_grindstone:grindstone", { local inv = meta:get_inventory() inv:set_size("input", 2) inv:set_size("output", 1) - local form = get_grindstone_formspec() - meta:set_string("formspec", form) + meta:set_string("formspec", grindstone_formspec) end, on_rightclick = function(pos, node, player, itemstack) if not player:get_player_control().sneak then local meta = minetest.get_meta(pos) update_grindstone_slots(meta) - meta:set_string("formspec", get_grindstone_formspec()) + meta:set_string("formspec", grindstone_formspec) end end, _mcl_blast_resistance = 6, @@ -337,7 +350,7 @@ minetest.register_node("mcl_grindstone:grindstone", { minetest.register_craft({ output = "mcl_grindstone:grindstone", recipe = { - { "mcl_core:stick", "mcl_stairs:slab_stone_rough", "mcl_core:stick"}, - { "group:wood", "", "group:wood"}, + { "mcl_core:stick", "mcl_stairs:slab_stone_rough", "mcl_core:stick" }, + { "group:wood", "", "group:wood" }, } }) diff --git a/mods/ITEMS/mcl_hoppers/init.lua b/mods/ITEMS/mcl_hoppers/init.lua index 15bc922ff..b4378b21b 100644 --- a/mods/ITEMS/mcl_hoppers/init.lua +++ b/mods/ITEMS/mcl_hoppers/init.lua @@ -12,15 +12,22 @@ end --[[ BEGIN OF NODE DEFINITIONS ]] local mcl_hoppers_formspec = table.concat({ - "size[9,7]", - "label[2,0;" .. F(C("#313131", S("Hopper"))) .. "]", - "list[context;main;2,0.5;5,1;]", - mcl_formspec.get_itemslot_bg(2, 0.5, 5, 1), - "label[0,2;" .. F(C("#313131", S("Inventory"))) .. "]", - "list[current_player;main;0,2.5;9,3;9]", - mcl_formspec.get_itemslot_bg(0, 2.5, 9, 3), - "list[current_player;main;0,5.74;9,1;]", - mcl_formspec.get_itemslot_bg(0, 5.74, 9, 1), + "formspec_version[4]", + "size[11.75,8.175]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Hopper"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(2.875, 0.75, 5, 1), + "list[context;main;2.875,0.75;5,1;]", + + "label[0.375,2.45;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 2.85, 9, 3), + "list[current_player;main;0.375,2.85;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 6.8, 9, 1), + "list[current_player;main;0.375,6.8;9,1;]", + "listring[context;main]", "listring[current_player;main]", }) @@ -31,7 +38,7 @@ local mcl_hoppers_formspec = table.concat({ local def_hopper = { inventory_image = "mcl_hoppers_item.png", wield_image = "mcl_hoppers_item.png", - groups = {pickaxey = 1, container = 2, deco_block = 1, hopper = 1}, + groups = { pickaxey = 1, container = 2, deco_block = 1, hopper = 1 }, drawtype = "nodebox", paramtype = "light", -- FIXME: mcl_hoppers_hopper_inside.png is unused by hoppers. @@ -47,25 +54,25 @@ local def_hopper = { type = "fixed", fixed = { --funnel walls - {-0.5, 0.0, 0.4, 0.5, 0.5, 0.5}, - {0.4, 0.0, -0.5, 0.5, 0.5, 0.5}, - {-0.5, 0.0, -0.5, -0.4, 0.5, 0.5}, - {-0.5, 0.0, -0.5, 0.5, 0.5, -0.4}, + { -0.5, 0.0, 0.4, 0.5, 0.5, 0.5 }, + { 0.4, 0.0, -0.5, 0.5, 0.5, 0.5 }, + { -0.5, 0.0, -0.5, -0.4, 0.5, 0.5 }, + { -0.5, 0.0, -0.5, 0.5, 0.5, -0.4 }, --funnel base - {-0.5, 0.0, -0.5, 0.5, 0.1, 0.5}, + { -0.5, 0.0, -0.5, 0.5, 0.1, 0.5 }, --spout - {-0.3, -0.3, -0.3, 0.3, 0.0, 0.3}, - {-0.1, -0.3, -0.1, 0.1, -0.5, 0.1}, + { -0.3, -0.3, -0.3, 0.3, 0.0, 0.3 }, + { -0.1, -0.3, -0.1, 0.1, -0.5, 0.1 }, }, }, selection_box = { type = "fixed", fixed = { --funnel - {-0.5, 0.0, -0.5, 0.5, 0.5, 0.5}, + { -0.5, 0.0, -0.5, 0.5, 0.5, 0.5 }, --spout - {-0.3, -0.3, -0.3, 0.3, 0.0, 0.3}, - {-0.1, -0.3, -0.1, 0.1, -0.5, 0.1}, + { -0.3, -0.3, -0.3, 0.3, 0.0, 0.3 }, + { -0.1, -0.3, -0.1, 0.1, -0.5, 0.1 }, }, }, is_ground_content = false, @@ -248,25 +255,25 @@ local def_hopper_side = { type = "fixed", fixed = { --funnel walls - {-0.5, 0.0, 0.4, 0.5, 0.5, 0.5}, - {0.4, 0.0, -0.5, 0.5, 0.5, 0.5}, - {-0.5, 0.0, -0.5, -0.4, 0.5, 0.5}, - {-0.5, 0.0, -0.5, 0.5, 0.5, -0.4}, + { -0.5, 0.0, 0.4, 0.5, 0.5, 0.5 }, + { 0.4, 0.0, -0.5, 0.5, 0.5, 0.5 }, + { -0.5, 0.0, -0.5, -0.4, 0.5, 0.5 }, + { -0.5, 0.0, -0.5, 0.5, 0.5, -0.4 }, --funnel base - {-0.5, 0.0, -0.5, 0.5, 0.1, 0.5}, + { -0.5, 0.0, -0.5, 0.5, 0.1, 0.5 }, --spout - {-0.3, -0.3, -0.3, 0.3, 0.0, 0.3}, - {-0.5, -0.3, -0.1, 0.1, -0.1, 0.1}, + { -0.3, -0.3, -0.3, 0.3, 0.0, 0.3 }, + { -0.5, -0.3, -0.1, 0.1, -0.1, 0.1 }, }, }, selection_box = { type = "fixed", fixed = { --funnel - {-0.5, 0.0, -0.5, 0.5, 0.5, 0.5}, + { -0.5, 0.0, -0.5, 0.5, 0.5, 0.5 }, --spout - {-0.3, -0.3, -0.3, 0.3, 0.0, 0.3}, - {-0.5, -0.3, -0.1, 0.1, -0.1, 0.1}, + { -0.3, -0.3, -0.3, 0.3, 0.0, 0.3 }, + { -0.5, -0.3, -0.1, 0.1, -0.1, 0.1 }, }, }, is_ground_content = false, @@ -559,8 +566,8 @@ end minetest.register_abm({ label = "Hopper/container item exchange", - nodenames = {"mcl_hoppers:hopper"}, - neighbors = {"group:container"}, + nodenames = { "mcl_hoppers:hopper" }, + neighbors = { "group:container" }, interval = 1.0, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) @@ -591,8 +598,8 @@ minetest.register_abm({ minetest.register_abm({ label = "Side-hopper/container item exchange", - nodenames = {"mcl_hoppers:hopper_side"}, - neighbors = {"group:container"}, + nodenames = { "mcl_hoppers:hopper_side" }, + neighbors = { "group:container" }, interval = 1.0, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) diff --git a/mods/ITEMS/mcl_smithing_table/init.lua b/mods/ITEMS/mcl_smithing_table/init.lua index dbb6c620f..5d0becad7 100644 --- a/mods/ITEMS/mcl_smithing_table/init.lua +++ b/mods/ITEMS/mcl_smithing_table/init.lua @@ -1,11 +1,13 @@ ---[[ -By EliasFleckenstein03 and Code-Sploit -]] +-- By EliasFleckenstein03 and Code-Sploit local S = minetest.get_translator("mcl_smithing_table") +local F = minetest.formspec_escape +local C = minetest.colorize + mcl_smithing_table = {} --- Function to upgrade diamond tool/armor to netherite tool/armor +---Function to upgrade diamond tool/armor to netherite tool/armor +---@param itemstack ItemStack function mcl_smithing_table.upgrade_item(itemstack) local def = itemstack:get_definition() @@ -29,28 +31,48 @@ function mcl_smithing_table.upgrade_item(itemstack) return itemstack end --- Badly copied over from mcl_anvils --- ToDo: Make better formspec +local formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", -local formspec = "size[9,9]" .. - "background[-0.19,-0.25;9.41,9.49;mcl_smithing_table_inventory.png]".. - "label[0,4.0;" .. minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))) .. "]" .. - "list[current_player;main;0,4.5;9,3;9]" .. - mcl_formspec.get_itemslot_bg(0,4.5,9,3) .. - "list[current_player;main;0,7.74;9,1;]" .. - mcl_formspec.get_itemslot_bg(0,7.74,9,1) .. - "list[context;diamond_item;1,2.5;1,1;]" .. - mcl_formspec.get_itemslot_bg(1,2.5,1,1) .. - "list[context;netherite;4,2.5;1,1;]" .. - mcl_formspec.get_itemslot_bg(4,2.5,1,1) .. - "list[context;upgraded_item;8,2.5;1,1;]" .. - mcl_formspec.get_itemslot_bg(8,2.5,1,1) .. - "label[3,0.1;" .. minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Upgrade Gear"))) .. "]" .. - "listring[context;output]".. - "listring[current_player;main]".. - "listring[context;input]".. - "listring[current_player;main]" + "label[4.125,0.375;" .. F(C(mcl_formspec.label_color, S("Upgrade Gear"))) .. "]", + "image[0.875,0.375;1.75,1.75;mcl_smithing_table_inventory_hammer.png]", + + mcl_formspec.get_itemslot_bg_v4(1.625, 2.6, 1, 1), + "list[context;diamond_item;1.625,2.6;1,1;]", + + "image[3.5,2.6;1,1;mcl_anvils_inventory_cross.png]", + + mcl_formspec.get_itemslot_bg_v4(5.375, 2.6, 1, 1), + "list[context;netherite;5.375,2.6;1,1;]", + + "image[6.75,2.6;2,1;mcl_anvils_inventory_arrow.png]", + + mcl_formspec.get_itemslot_bg_v4(9.125, 2.6, 1, 1), + "list[context;upgraded_item;9.125,2.6;1,1;]", + + -- Player Inventory + + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + + -- Listrings + + "listring[context;diamond_item]", + "listring[current_player;main]", + "listring[context;netherite]", + "listring[current_player;main]", + "listring[context;upgraded_item]", + "listring[current_player;main]", + "listring[current_player;main]", + "listring[context;diamond_item]", +}) + +---@param pos Vector local function reset_upgraded_item(pos) local inv = minetest.get_meta(pos):get_inventory() local upgraded_item @@ -66,8 +88,7 @@ minetest.register_node("mcl_smithing_table:table", { description = S("Smithing table"), -- ToDo: Add _doc_items_longdesc and _doc_items_usagehelp - stack_max = 64, - groups = {pickaxey = 2, deco_block = 1}, + groups = { pickaxey = 2, deco_block = 1 }, tiles = { "mcl_smithing_table_top.png", @@ -92,7 +113,8 @@ minetest.register_node("mcl_smithing_table:table", { end, allow_metadata_inventory_put = function(pos, listname, index, stack, player) - if listname == "diamond_item" and mcl_smithing_table.upgrade_item(stack) or listname == "netherite" and stack:get_name() == "mcl_nether:netherite_ingot" then + if listname == "diamond_item" and mcl_smithing_table.upgrade_item(stack) or + listname == "netherite" and stack:get_name() == "mcl_nether:netherite_ingot" then return stack:get_count() end @@ -119,7 +141,7 @@ minetest.register_node("mcl_smithing_table:table", { take_item("netherite") -- ToDo: make epic sound - minetest.sound_play("mcl_smithing_table_upgrade", {pos = pos, max_hear_distance = 16}) + minetest.sound_play("mcl_smithing_table_upgrade", { pos = pos, max_hear_distance = 16 }) end if listname == "upgraded_item" then if stack:get_name() == "mcl_farming:hoe_netherite" then @@ -138,8 +160,8 @@ minetest.register_node("mcl_smithing_table:table", { minetest.register_craft({ output = "mcl_smithing_table:table", recipe = { - {"mcl_core:iron_ingot", "mcl_core:iron_ingot", ""}, - {"group:wood", "group:wood", ""}, - {"group:wood", "group:wood", ""} - } + { "mcl_core:iron_ingot", "mcl_core:iron_ingot", "" }, + { "group:wood", "group:wood", "" }, + { "group:wood", "group:wood", "" } + }, }) diff --git a/mods/ITEMS/mcl_smithing_table/mod.conf b/mods/ITEMS/mcl_smithing_table/mod.conf index aee93fa65..1c12cb483 100644 --- a/mods/ITEMS/mcl_smithing_table/mod.conf +++ b/mods/ITEMS/mcl_smithing_table/mod.conf @@ -1,2 +1,2 @@ name = mcl_smithing_table -depends = mcl_colors, mcl_formspec +depends = mcl_colors, mcl_formspec, mcl_anvils diff --git a/mods/ITEMS/mcl_smoker/init.lua b/mods/ITEMS/mcl_smoker/init.lua index 4a4cfca15..757f13054 100644 --- a/mods/ITEMS/mcl_smoker/init.lua +++ b/mods/ITEMS/mcl_smoker/init.lua @@ -1,5 +1,6 @@ - local S = minetest.get_translator(minetest.get_current_modname()) +local C = minetest.colorize +local F = minetest.formspec_escape local LIGHT_ACTIVE_FURNACE = 13 @@ -8,60 +9,82 @@ local LIGHT_ACTIVE_FURNACE = 13 -- local function active_formspec(fuel_percent, item_percent) - return "size[9,8.75]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Smoker"))).."]".. - "list[context;src;2.75,0.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. - "list[context;fuel;2.75,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,2.5,1,1).. - "list[context;dst;5.75,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(5.75,1.5,1,1).. - "image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:".. - (100-fuel_percent)..":default_furnace_fire_fg.png]".. - "image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[lowpart:".. - (item_percent)..":gui_furnace_arrow_fg.png^[transformR270]".. - -- Craft guide button temporarily removed due to Minetest bug. - -- TODO: Add it back when the Minetest bug is fixed. - --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. - --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. - "listring[context;dst]".. - "listring[current_player;main]".. - "listring[context;src]".. - "listring[current_player;main]".. - "listring[context;fuel]".. - "listring[current_player;main]" + return table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Smoker"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(3.5, 0.75, 1, 1), + "list[context;src;3.5,0.75;1,1;]", + + "image[3.5,2;1,1;default_furnace_fire_bg.png^[lowpart:" .. + (100 - fuel_percent) .. ":default_furnace_fire_fg.png]", + + mcl_formspec.get_itemslot_bg_v4(3.5, 3.25, 1, 1), + "list[context;fuel;3.5,3.25;1,1;]", + + "image[5.25,2;1.5,1;gui_furnace_arrow_bg.png^[lowpart:" .. + (item_percent) .. ":gui_furnace_arrow_fg.png^[transformR270]", + mcl_formspec.get_itemslot_bg_v4(7.875, 2, 1, 1, 0.2), + "list[context;dst;7.875,2;1,1;]", + + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + + -- Craft guide button temporarily removed due to Minetest bug. + -- TODO: Add it back when the Minetest bug is fixed. + --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. + --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. + + "listring[context;dst]", + "listring[current_player;main]", + "listring[context;src]", + "listring[current_player;main]", + "listring[context;fuel]", + "listring[current_player;main]", + }) end -local inactive_formspec = "size[9,8.75]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Smoker"))).."]".. - "list[context;src;2.75,0.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. - "list[context;fuel;2.75,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,2.5,1,1).. - "list[context;dst;5.75,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(5.75,1.5,1,1).. - "image[2.75,1.5;1,1;default_furnace_fire_bg.png]".. - "image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[transformR270]".. +local inactive_formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Smoker"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(3.5, 0.75, 1, 1), + "list[context;src;3.5,0.75;1,1;]", + + "image[3.5,2;1,1;default_furnace_fire_bg.png]", + + mcl_formspec.get_itemslot_bg_v4(3.5, 3.25, 1, 1), + "list[context;fuel;3.5,3.25;1,1;]", + + "image[5.25,2;1.5,1;gui_furnace_arrow_bg.png^[transformR270]", + + mcl_formspec.get_itemslot_bg_v4(7.875, 2, 1, 1, 0.2), + "list[context;dst;7.875,2;1,1;]", + + "label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3), + "list[current_player;main;0.375,5.1;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1), + "list[current_player;main;0.375,9.05;9,1;]", + -- Craft guide button temporarily removed due to Minetest bug. -- TODO: Add it back when the Minetest bug is fixed. --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. - "listring[context;dst]".. - "listring[current_player;main]".. - "listring[context;src]".. - "listring[current_player;main]".. - "listring[context;fuel]".. - "listring[current_player;main]" + + "listring[context;dst]", + "listring[current_player;main]", + "listring[context;src]", + "listring[current_player;main]", + "listring[context;fuel]", + "listring[current_player;main]", +}) + local receive_fields = function(pos, formname, fields, sender) if fields.craftguide then @@ -71,7 +94,7 @@ end local function give_xp(pos, player) local meta = minetest.get_meta(pos) - local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2),-1.95) + local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2), -1.95) local xp = meta:get_int("xp") if xp > 0 then if player then @@ -98,7 +121,7 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player) -- Test stack with size 1 because we burn one fuel at a time local teststack = ItemStack(stack) teststack:set_count(1) - local output, decremented_input = minetest.get_craft_result({method="fuel", width=1, items={teststack}}) + local output, decremented_input = minetest.get_craft_result({ method = "fuel", width = 1, items = { teststack } }) if output.time ~= 0 then -- Only allow to place 1 item if fuel get replaced by recipe. -- This is the case for lava buckets. @@ -292,7 +315,7 @@ local function smoker_node_timer(pos, elapsed) -- Check if we have cookable content: cookable local aftercooked - cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) + cooked, aftercooked = minetest.get_craft_result({ method = "cooking", width = 1, items = srclist }) cookable = minetest.get_item_group(inv:get_stack("src", 1):get_name(), "smoker_cookable") == 1 if cookable then -- Successful cooking requires space in dst slot and time @@ -310,7 +333,7 @@ local function smoker_node_timer(pos, elapsed) if cookable and not active then -- We need to get new fuel local afterfuel - fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) + fuel, afterfuel = minetest.get_craft_result({ method = "fuel", width = 1, items = fuellist }) if fuel.time == 0 then -- No valid fuel in fuel list -- stop @@ -343,7 +366,7 @@ local function smoker_node_timer(pos, elapsed) srclist = inv:get_list("src") src_time = 0 - meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count + meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count end end @@ -390,9 +413,9 @@ local function smoker_node_timer(pos, elapsed) meta:set_float("fuel_time", fuel_time) meta:set_float("src_time", src_time) if srclist then - meta:set_string("src_item", src_item) + meta:set_string("src_item", src_item) else - meta:set_string("src_item", "") + meta:set_string("src_item", "") end meta:set_string("formspec", formspec) @@ -415,13 +438,14 @@ end minetest.register_node("mcl_smoker:smoker", { description = S("Smoker"), _tt_help = S("Cooks food faster than furnace"), - _doc_items_longdesc = S("Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace."), + _doc_items_longdesc = S( + "Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace."), _doc_items_usagehelp = - S("Use the smoker to open the furnace menu.").."\n".. - S("Place a furnace fuel in the lower slot and the source material in the upper slot.").."\n".. - S("The smoker will slowly use its fuel to smelt the item.").."\n".. - S("The result will be placed into the output slot at the right side.").."\n".. - S("Use the recipe book to see what foods you can smelt, what you can use as fuel and how long it will burn."), + S("Use the smoker to open the furnace menu.") .. "\n" .. + S("Place a furnace fuel in the lower slot and the source material in the upper slot.") .. "\n" .. + S("The smoker will slowly use its fuel to smelt the item.") .. "\n" .. + S("The result will be placed into the output slot at the right side.") .. "\n" .. + S("Use the recipe book to see what foods you can smelt, what you can use as fuel and how long it will burn."), _doc_items_hidden = false, tiles = { "smoker_top.png", "smoker_bottom.png", @@ -429,7 +453,7 @@ minetest.register_node("mcl_smoker:smoker", { "smoker_side.png", "smoker_front.png" }, paramtype2 = "facedir", - groups = {pickaxey=1, container=4, deco_block=1, material_stone=1}, + groups = { pickaxey = 1, container = 4, deco_block = 1, material_stone = 1 }, is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(), @@ -439,10 +463,14 @@ minetest.register_node("mcl_smoker:smoker", { local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() - for _, listname in ipairs({"src", "dst", "fuel"}) do + for _, listname in ipairs({ "src", "dst", "fuel" }) do local stack = inv:get_stack(listname, 1) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = { + x = pos.x + math.random(0, 10) / 10 - 0.5, + y = pos.y, + z = pos.z + math.random(0, 10) / 10 - 0.5 + } minetest.add_item(p, stack) end end @@ -499,14 +527,16 @@ minetest.register_node("mcl_smoker:smoker_active", { tiles = { "smoker_top.png", "smoker_bottom.png", "smoker_side.png", "smoker_side.png", - "smoker_side.png", {name = "smoker_front_on.png", - animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 48}}, + "smoker_side.png", { + name = "smoker_front_on.png", + animation = { type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 48 } + }, }, paramtype2 = "facedir", paramtype = "light", light_source = LIGHT_ACTIVE_FURNACE, drop = "mcl_smoker:smoker", - groups = {pickaxey=1, container=4, deco_block=1, not_in_creative_inventory=1, material_stone=1}, + groups = { pickaxey = 1, container = 4, deco_block = 1, not_in_creative_inventory = 1, material_stone = 1 }, is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(), on_timer = smoker_node_timer, @@ -516,10 +546,14 @@ minetest.register_node("mcl_smoker:smoker_active", { local meta2 = meta meta:from_table(oldmetadata) local inv = meta:get_inventory() - for _, listname in ipairs({"src", "dst", "fuel"}) do + for _, listname in ipairs({ "src", "dst", "fuel" }) do local stack = inv:get_stack(listname, 1) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = { + x = pos.x + math.random(0, 10) / 10 - 0.5, + y = pos.y, + z = pos.z + math.random(0, 10) / 10 - 0.5 + } minetest.add_item(p, stack) end end @@ -550,9 +584,9 @@ minetest.register_node("mcl_smoker:smoker_active", { minetest.register_craft({ output = "mcl_smoker:smoker", recipe = { - { "", "group:tree", "" }, + { "", "group:tree", "" }, { "group:tree", "mcl_furnaces:furnace", "group:tree" }, - { "", "group:tree", "" }, + { "", "group:tree", "" }, } }) @@ -564,7 +598,7 @@ end minetest.register_lbm({ label = "Active smoker flame particles", name = "mcl_smoker:flames", - nodenames = {"mcl_smoker:smoker_active"}, + nodenames = { "mcl_smoker:smoker_active" }, run_at_every_load = true, action = function(pos, node) spawn_flames(pos, node.param2) diff --git a/mods/PLAYER/mcl_gamemode/API.md b/mods/PLAYER/mcl_gamemode/API.md new file mode 100644 index 000000000..24651301e --- /dev/null +++ b/mods/PLAYER/mcl_gamemode/API.md @@ -0,0 +1,27 @@ +# `mcl_gamemode` + +## `mcl_gamemode.gamemodes` + +List of availlable gamemodes. + +Currently `{"survival", "creative"}` + +## `mcl_gamemode.get_gamemode(player)` + +Get the player's gamemode. + +Returns "survival" or "creative". + +## `mcl_gamemode.set_gamemode(player, gamemode)` + +Set the player's gamemode. + +gamemode: "survival" or "creative" + +## `mcl_gamemode.register_on_gamemode_change(function(player, old_gamemode, new_gamemode))` + +Register a function that will be called when `mcl_gamemode.set_gamemode` is called. + +## `mcl_gamemode.registered_on_gamemode_change` + +Map of registered on_gamemode_change. diff --git a/mods/PLAYER/mcl_gamemode/init.lua b/mods/PLAYER/mcl_gamemode/init.lua new file mode 100644 index 000000000..a43a9c1ff --- /dev/null +++ b/mods/PLAYER/mcl_gamemode/init.lua @@ -0,0 +1,84 @@ +local S = minetest.get_translator("mcl_gamemode") + +mcl_gamemode = {} + +mcl_gamemode.gamemodes = { + "survival", + "creative", +} + +---@param n any +---@param h table +---@return boolean +local function in_table(n, h) + for k, v in pairs(h) do + if v == n then return true end + end + return false +end + +---@type fun(player: mt.PlayerObjectRef, old_gamemode: '"survival"'|'"creative"', new_gamemode: '"survival"'|'"creative"')[] +mcl_gamemode.registered_on_gamemode_change = {} + +---@param func fun(player: mt.PlayerObjectRef, old_gamemode: '"survival"'|'"creative"', new_gamemode: '"survival"'|'"creative"') +function mcl_gamemode.register_on_gamemode_change(func) + table.insert(mcl_gamemode.registered_on_gamemode_change, func) +end + +---@param player mt.PlayerObjectRef +---@param gamemode '"survival"'|'"creative"' +function mcl_gamemode.set_gamemode(player, gamemode) + local meta = player:get_meta() + local old_gamemode = meta:get_string("gamemode") + meta:set_string("gamemode", gamemode) + for _, f in ipairs(mcl_gamemode.registered_on_gamemode_change) do + f(player, old_gamemode, gamemode) + end +end + +local mt_is_creative_enabled = minetest.is_creative_enabled + +---@param player mt.PlayerObjectRef +---@return '"survival"'|'"creative"' +function mcl_gamemode.get_gamemode(player) + if mt_is_creative_enabled(player:get_player_name()) then + return "creative" + end + return player:get_meta():get_string("gamemode") +end + +function minetest.is_creative_enabled(name) + if mt_is_creative_enabled(name) then return true end + if not name then return false end + local p = minetest.get_player_by_name(name) + if p then + return p:get_meta():get_string("gamemode") == "creative" + end + return false +end + +minetest.register_chatcommand("gamemode", { + params = S("[] []"), + description = S("Change gamemode (survival/creative) for yourself or player"), + privs = { server = true }, + func = function(n, param) + -- Full input validation ( just for @erlehmann <3 ) + local p = minetest.get_player_by_name(n) + local args = param:split(" ") + if args[2] ~= nil then + p = minetest.get_player_by_name(args[2]) + end + if not p then + return false, S("Player not online") + end + if args[1] ~= nil and not in_table(args[1], mcl_gamemode.gamemodes) then + return false, S("Gamemode " .. args[1] .. " does not exist.") + elseif args[1] ~= nil then + mcl_gamemode.set_gamemode(p, args[1]) + end + --Result message - show effective game mode + local gm = p:get_meta():get_string("gamemode") + if gm == "" then gm = mcl_gamemode.gamemodes[1] end + return true, S("Gamemode for player ") .. n .. S(": " .. gm) + end +}) diff --git a/mods/PLAYER/mcl_gamemode/mod.conf b/mods/PLAYER/mcl_gamemode/mod.conf new file mode 100644 index 000000000..03eade707 --- /dev/null +++ b/mods/PLAYER/mcl_gamemode/mod.conf @@ -0,0 +1 @@ +name = mcl_gamemode \ No newline at end of file diff --git a/mods/PLAYER/mcl_meshhand/init.lua b/mods/PLAYER/mcl_meshhand/init.lua index 6d1177b18..c42ff8081 100644 --- a/mods/PLAYER/mcl_meshhand/init.lua +++ b/mods/PLAYER/mcl_meshhand/init.lua @@ -89,6 +89,10 @@ minetest.register_on_joinplayer(function(player) player:get_inventory():set_size("hand", 1) end) +mcl_gamemode.register_on_gamemode_change(function(player) + mcl_meshhand.update_player(player) +end) + if mcl_skins_enabled then mcl_player.register_on_visual_change(mcl_meshhand.update_player) else diff --git a/mods/PLAYER/mcl_meshhand/mod.conf b/mods/PLAYER/mcl_meshhand/mod.conf index 687932514..fd10c259c 100644 --- a/mods/PLAYER/mcl_meshhand/mod.conf +++ b/mods/PLAYER/mcl_meshhand/mod.conf @@ -1,5 +1,5 @@ name = mcl_meshhand author = jordan4ibanez description = Applies the player skin texture to the hand. -depends = mcl_tools, mcl_player +depends = mcl_tools, mcl_player, mcl_gamemode optional_depends = mcl_skins, mcl_custom_skins diff --git a/mods/PLAYER/mcl_player/init.lua b/mods/PLAYER/mcl_player/init.lua index 084fe48a1..288b697e1 100644 --- a/mods/PLAYER/mcl_player/init.lua +++ b/mods/PLAYER/mcl_player/init.lua @@ -1,3 +1,4 @@ +local string = string local sf = string.format -- Minetest 0.4 mod: player @@ -11,15 +12,16 @@ local animation_blend = 0 local function get_mouse_button(player) local controls = player:get_player_control() local get_wielded_item_name = player:get_wielded_item():get_name() - if controls.RMB and not string.find(get_wielded_item_name, "mcl_bows:bow") and not string.find(get_wielded_item_name, "mcl_bows:crossbow") and - not mcl_shields.wielding_shield(player, 1) and not mcl_shields.wielding_shield(player, 2) or controls.LMB then + if controls.RMB and not string.find(get_wielded_item_name, "mcl_bows:bow") and + not string.find(get_wielded_item_name, "mcl_bows:crossbow") and + not mcl_shields.wielding_shield(player, 1) and not mcl_shields.wielding_shield(player, 2) or controls.LMB then return true else return false end end -mcl_player.registered_player_models = { } +mcl_player.registered_player_models = {} -- Local for speed. local models = mcl_player.registered_player_models @@ -49,7 +51,7 @@ function mcl_player.player_get_animation(player) model = player_model[name], textures = textures, animation = player_anim[name], - visibility = player_visibility[name] + visibility = player_visible[name] } end @@ -94,7 +96,7 @@ function mcl_player.player_set_model(player, model_name) player:set_properties({ mesh = model_name, visual = "mesh", - visual_size = model.visual_size or {x=1, y=1}, + visual_size = model.visual_size or { x = 1, y = 1 }, damage_texture_modifier = "^[colorize:red:130", }) update_player_textures(player) @@ -133,6 +135,13 @@ function mcl_player.player_set_armor(player, texture) update_player_textures(player) end +---@param player mt.PlayerObjectRef +---@param x number +---@param y number +---@param w number +---@param h number +---@param fsname string +---@return string function mcl_player.get_player_formspec_model(player, x, y, w, h, fsname) local name = player:get_player_name() local model = player_model[name] @@ -165,7 +174,8 @@ minetest.register_on_joinplayer(function(player) local name = player:get_player_name() mcl_player.player_attached[name] = false player_visible[name] = true - player_textures[name] = {"character.png", "blank.png", "blank.png"} + player_textures[name] = { "character.png", "blank.png", "blank.png" } + --player:set_local_animation({x=0, y=79}, {x=168, y=187}, {x=189, y=198}, {x=200, y=219}, 30) player:set_fov(86.1) -- see >>> end) @@ -221,11 +231,13 @@ minetest.register_globalstep(function(dtime) elseif mcl_playerplus.elytra[player] and mcl_playerplus.elytra[player].active then player_set_animation(player, "stand") elseif walking and velocity.x > 0.35 - or walking and velocity.x < -0.35 - or walking and velocity.z > 0.35 - or walking and velocity.z < -0.35 then + or walking and velocity.x < -0.35 + or walking and velocity.z > 0.35 + or walking and velocity.z < -0.35 then local wielded_itemname = player:get_wielded_item():get_name() - local no_arm_moving = string.find(wielded_itemname, "mcl_bows:bow") or mcl_shields.wielding_shield(player, 1) or mcl_shields.wielding_shield(player, 2) + local no_arm_moving = string.find(wielded_itemname, "mcl_bows:bow") or + mcl_shields.wielding_shield(player, 1) or + mcl_shields.wielding_shield(player, 2) if player_sneak[name] ~= controls.sneak then player_anim[name] = nil player_sneak[name] = controls.sneak @@ -234,7 +246,8 @@ minetest.register_globalstep(function(dtime) player_set_animation(player, "swim_walk_mine", animation_speed_mod) elseif not controls.sneak and head_in_water and is_sprinting == true then player_set_animation(player, "swim_walk", animation_speed_mod) - elseif no_arm_moving and controls.RMB and controls.sneak or string.find(wielded_itemname, "mcl_bows:crossbow_") and controls.sneak then + elseif no_arm_moving and controls.RMB and controls.sneak or + string.find(wielded_itemname, "mcl_bows:crossbow_") and controls.sneak then player_set_animation(player, "bow_sneak", animation_speed_mod) elseif no_arm_moving and controls.RMB or string.find(wielded_itemname, "mcl_bows:crossbow_") then player_set_animation(player, "bow_walk", animation_speed_mod) diff --git a/textures/crafting_formspec_arrow.png b/textures/crafting_formspec_arrow.png new file mode 100644 index 000000000..12b9c1970 Binary files /dev/null and b/textures/crafting_formspec_arrow.png differ diff --git a/textures/crafting_inventory_creative.png b/textures/crafting_inventory_creative.png deleted file mode 100644 index 43664452b..000000000 Binary files a/textures/crafting_inventory_creative.png and /dev/null differ diff --git a/textures/crafting_inventory_creative_survival.png b/textures/crafting_inventory_creative_survival.png deleted file mode 100644 index ad53b5f4f..000000000 Binary files a/textures/crafting_inventory_creative_survival.png and /dev/null differ diff --git a/textures/grindstone_gui_9.png b/textures/grindstone_gui_9.png new file mode 100644 index 000000000..b2fffcb56 Binary files /dev/null and b/textures/grindstone_gui_9.png differ diff --git a/textures/mcl_anvils_inventory_arrow.png b/textures/mcl_anvils_inventory_arrow.png new file mode 100644 index 000000000..722d6f636 Binary files /dev/null and b/textures/mcl_anvils_inventory_arrow.png differ diff --git a/textures/mcl_anvils_inventory_cross.png b/textures/mcl_anvils_inventory_cross.png new file mode 100644 index 000000000..ec13632ca Binary files /dev/null and b/textures/mcl_anvils_inventory_cross.png differ diff --git a/textures/mcl_anvils_inventory_hammer.png b/textures/mcl_anvils_inventory_hammer.png new file mode 100644 index 000000000..66c1f5f91 Binary files /dev/null and b/textures/mcl_anvils_inventory_hammer.png differ diff --git a/textures/mcl_book_book_empty_slot.png b/textures/mcl_book_book_empty_slot.png new file mode 100644 index 000000000..e6a50bd9e Binary files /dev/null and b/textures/mcl_book_book_empty_slot.png differ diff --git a/textures/mcl_inventory_background9.png b/textures/mcl_inventory_background9.png new file mode 100644 index 000000000..d774fd319 Binary files /dev/null and b/textures/mcl_inventory_background9.png differ diff --git a/textures/mcl_smithing_table_bottom.png b/textures/mcl_smithing_table_bottom.png index d44c0773e..cca0ebf14 100644 Binary files a/textures/mcl_smithing_table_bottom.png and b/textures/mcl_smithing_table_bottom.png differ diff --git a/textures/mcl_smithing_table_front.png b/textures/mcl_smithing_table_front.png index bdf52e354..eef16e6aa 100644 Binary files a/textures/mcl_smithing_table_front.png and b/textures/mcl_smithing_table_front.png differ diff --git a/textures/mcl_smithing_table_inventory_hammer.png b/textures/mcl_smithing_table_inventory_hammer.png new file mode 100644 index 000000000..48a21e97d Binary files /dev/null and b/textures/mcl_smithing_table_inventory_hammer.png differ diff --git a/textures/mcl_smithing_table_side.png b/textures/mcl_smithing_table_side.png index fbc1a9a23..d93a7906c 100644 Binary files a/textures/mcl_smithing_table_side.png and b/textures/mcl_smithing_table_side.png differ diff --git a/textures/mcl_smithing_table_top.png b/textures/mcl_smithing_table_top.png index 63c6aea35..be7abee62 100644 Binary files a/textures/mcl_smithing_table_top.png and b/textures/mcl_smithing_table_top.png differ