Merge pull request 'Formspec Refactoring' (#2635) from AFCMS/MineClone2:formspec-v4 into master
Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/2635 Reviewed-by: 𝕵𝖔𝖍𝖆𝖓𝖓𝖊𝖘 𝕱𝖗𝖎𝖙𝖟 <mrrar@noreply.git.minetest.land> Reviewed-by: ancientmarinerdev <ancientmariner_dev@proton.me>
@ -1,3 +1,5 @@
|
||||
---@diagnostic disable
|
||||
|
||||
unused_args = false
|
||||
allow_defined_top = true
|
||||
max_line_length = false
|
||||
|
22
.luarc.json
Normal file
@ -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"]
|
||||
}
|
@ -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)
|
||||
|
@ -1,3 +1,4 @@
|
||||
name = mcl_experience
|
||||
author = oilboi
|
||||
description = eXPerience mod
|
||||
depends = mcl_gamemode
|
||||
|
40
mods/HUD/mcl_formspec/API.md
Normal file
@ -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
|
21
mods/HUD/mcl_formspec/FORMSPEC_GUIDE.md
Normal file
@ -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)
|
@ -1,5 +1,13 @@
|
||||
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
|
||||
@ -9,3 +17,40 @@ function mcl_formspec.get_itemslot_bg(x, y, w, h)
|
||||
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
|
||||
end
|
||||
|
35
mods/HUD/mcl_inventory/API.md
Normal file
@ -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,
|
||||
```
|
@ -3,19 +3,35 @@ local F = minetest.formspec_escape
|
||||
local C = minetest.colorize
|
||||
|
||||
-- Prepare player info table
|
||||
---@type table<string, {page: string, filter: string, start_i: integer, inv_size: integer}>
|
||||
local players = {}
|
||||
|
||||
-- Containing all the items for each Creative Mode tab
|
||||
---@type table<string, string[]>
|
||||
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
|
||||
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 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
|
||||
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,6 +183,8 @@ 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 })
|
||||
@ -160,6 +198,8 @@ 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, {
|
||||
@ -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<string, {[0]: number, [1]: number}>
|
||||
local noffset = {}
|
||||
|
||||
-- String position of tab button background image, indexed by tab name
|
||||
---@type table<string, string>
|
||||
local offset = {}
|
||||
|
||||
-- String position of tab button, indexed by tab name
|
||||
---@type table<string, string>
|
||||
local boffset = {}
|
||||
|
||||
-- Used to determine the tab button background image
|
||||
---@type table<string, ""|"_down">
|
||||
local button_bg_postfix = {}
|
||||
|
||||
-- Tab caption/tooltip translated string, indexed by tab name
|
||||
---@type table<string, string>
|
||||
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")
|
||||
@ -240,23 +301,23 @@ next_noffset("inv", true)
|
||||
|
||||
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,120 +352,8 @@ filtername["inv"] = S("Survival Inventory")
|
||||
bg["default"] = dark_bg
|
||||
end]]
|
||||
|
||||
local function get_stack_size(player)
|
||||
return player:get_meta():get_int("mcl_inventory:switch_stack")
|
||||
end
|
||||
|
||||
local function set_stack_size(player, n)
|
||||
player:get_meta():set_int("mcl_inventory:switch_stack", n)
|
||||
end
|
||||
|
||||
minetest.register_on_joinplayer(function (player)
|
||||
if get_stack_size(player) == 0 then
|
||||
set_stack_size(player, 64)
|
||||
end
|
||||
end)
|
||||
|
||||
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 inv_size = players[playername].inv_size
|
||||
local filter = players[playername].filter
|
||||
local pagemax = math.max(1, math.floor((inv_size-1) / (9*5) + 1))
|
||||
local main_list
|
||||
local listrings = "listring[detached:creative_"..playername..";main]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[detached:trash;main]"
|
||||
|
||||
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]"
|
||||
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]"
|
||||
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]"
|
||||
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]"
|
||||
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]"
|
||||
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) ..
|
||||
|
||||
-- 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 ..
|
||||
|
||||
-- Player preview
|
||||
mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "") ..
|
||||
|
||||
-- Crafting guide button
|
||||
"image_button[9,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")) .. "]" ..
|
||||
|
||||
-- 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
|
||||
|
||||
-- For shortcuts
|
||||
listrings = listrings ..
|
||||
"listring[detached:"..playername.."_armor;armor]"..
|
||||
"listring[current_player;main]"
|
||||
else
|
||||
-- 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;]"
|
||||
end
|
||||
|
||||
-- Item name representing a tab, indexed by tab name
|
||||
---@type table<string, string>
|
||||
local tab_icon = {
|
||||
blocks = "mcl_core:brick_block",
|
||||
deco = "mcl_flowers:peony",
|
||||
@ -420,66 +369,233 @@ function mcl_inventory.set_creative_formspec(player)
|
||||
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)
|
||||
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 page = players[playername].page
|
||||
local inv_size = players[playername].inv_size
|
||||
local filter = players[playername].filter
|
||||
|
||||
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 = 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
|
||||
|
||||
if name == "inv" then
|
||||
-- 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[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[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[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[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[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 = 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
|
||||
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
|
||||
"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[11.575,0.825;1.1,1.1;craftguide_book.png;__mcl_craftguide;]",
|
||||
"tooltip[__mcl_craftguide;" .. F(S("Recipe book")) .. "]",
|
||||
|
||||
-- Help button
|
||||
"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[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[current_player;main]"
|
||||
else
|
||||
|
||||
--local nb_lines = math.ceil(inv_size / 9)
|
||||
-- Creative inventory slots
|
||||
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
|
||||
|
||||
---@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
|
||||
player:set_inventory_formspec(formspec)
|
||||
@ -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)
|
||||
|
@ -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,7 +19,7 @@ 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}
|
||||
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)
|
||||
@ -34,9 +38,12 @@ 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
|
||||
@ -46,84 +53,20 @@ function return_fields(player, name)
|
||||
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
|
||||
@ -138,7 +81,10 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
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("[<gamemode>] [<player>]"),
|
||||
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
|
||||
})
|
||||
|
@ -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
|
||||
|
224
mods/HUD/mcl_inventory/survival.lua
Normal file
@ -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)
|
@ -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
|
||||
@ -88,8 +101,7 @@ local dispenserdef = {
|
||||
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,11 +119,11 @@ 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]
|
||||
@ -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
|
||||
@ -301,7 +314,8 @@ 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._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" ..
|
||||
|
||||
|
@ -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
|
||||
@ -61,8 +74,7 @@ local dropperdef = {
|
||||
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)
|
||||
@ -106,9 +118,9 @@ local dropperdef = {
|
||||
if node.name == "mcl_droppers:dropper" then
|
||||
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
|
||||
@ -136,11 +148,11 @@ 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
|
||||
@ -166,6 +178,7 @@ 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",
|
||||
|
@ -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,35 +12,59 @@ 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)
|
||||
@ -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")
|
||||
@ -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
|
||||
@ -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
|
||||
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,
|
||||
@ -305,12 +330,13 @@ local function damage_anvil(pos)
|
||||
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,6 +347,8 @@ 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
|
||||
@ -330,16 +358,19 @@ local function damage_anvil_by_falling(pos, distance)
|
||||
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,
|
||||
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,
|
||||
@ -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
|
||||
@ -530,10 +559,13 @@ 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!")
|
||||
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("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("• 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.")
|
||||
|
||||
@ -542,14 +574,16 @@ 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
|
||||
|
||||
|
@ -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)
|
||||
@ -47,15 +48,18 @@ local function barrel_open(pos, node, clicker)
|
||||
minetest.show_formspec(playername,
|
||||
"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),
|
||||
"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]",
|
||||
})
|
||||
@ -66,6 +70,7 @@ local function barrel_open(pos, node, clicker)
|
||||
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
|
||||
@ -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.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]
|
||||
@ -106,7 +114,9 @@ minetest.register_node("mcl_barrels:barrel_closed", {
|
||||
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,
|
||||
@ -155,7 +165,15 @@ minetest.register_node("mcl_barrels:barrel_open", {
|
||||
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,
|
||||
@ -196,7 +214,7 @@ minetest.register_craft({
|
||||
{ "group:wood", "group:wood_slab", "group:wood" },
|
||||
{ "group:wood", "", "group:wood" },
|
||||
{ "group:wood", "group:wood_slab", "group:wood" },
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
|
@ -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]"..
|
||||
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]"
|
||||
|
||||
"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
|
||||
@ -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,
|
||||
@ -415,7 +438,8 @@ 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" ..
|
||||
@ -442,8 +466,7 @@ minetest.register_node("mcl_blast_furnace:blast_furnace", {
|
||||
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,8 +522,10 @@ 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",
|
||||
@ -519,7 +544,11 @@ minetest.register_node("mcl_blast_furnace:blast_furnace_active", {
|
||||
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
|
||||
@ -570,4 +599,3 @@ minetest.register_lbm({
|
||||
spawn_flames(pos, node.param2)
|
||||
end,
|
||||
})
|
||||
|
||||
|
@ -85,7 +85,8 @@ 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
|
||||
@ -106,7 +107,8 @@ 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
|
||||
@ -125,7 +127,9 @@ 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"..
|
||||
_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 },
|
||||
@ -151,10 +155,13 @@ minetest.register_on_player_receive_fields(function ( player, formname, fields )
|
||||
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))).."]"..
|
||||
"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")).."]"..
|
||||
"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
|
||||
@ -202,10 +209,14 @@ 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 },
|
||||
stack_max = 16,
|
||||
@ -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")
|
||||
@ -380,15 +394,19 @@ local function bookshelf_gui(pos, node, clicker)
|
||||
minetest.show_formspec(playername,
|
||||
"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),
|
||||
"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]",
|
||||
})
|
||||
@ -413,8 +431,14 @@ minetest.register_node("mcl_books:bookshelf", {
|
||||
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,
|
||||
@ -464,4 +488,3 @@ minetest.register_craft({
|
||||
recipe = "mcl_books:bookshelf",
|
||||
burntime = 15,
|
||||
})
|
||||
|
||||
|
@ -1,4 +1,13 @@
|
||||
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
|
||||
@ -50,7 +59,7 @@ local entity_animations = {
|
||||
speed = 25,
|
||||
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,
|
||||
@ -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
|
||||
@ -239,11 +269,13 @@ local function chest_update_after_close(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")
|
||||
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")
|
||||
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")
|
||||
@ -255,7 +287,8 @@ local function chest_update_after_close(pos)
|
||||
|
||||
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")
|
||||
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,7 +311,9 @@ 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
|
||||
@ -361,10 +398,9 @@ 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 },
|
||||
on_construct = function(pos, node)
|
||||
@ -381,7 +417,8 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
||||
local players = minetest.get_connected_players()
|
||||
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
|
||||
@ -398,16 +435,24 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
||||
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,
|
||||
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)
|
||||
@ -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
|
||||
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
|
||||
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")
|
||||
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 })
|
||||
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")
|
||||
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)
|
||||
@ -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)
|
||||
@ -524,14 +583,23 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
||||
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,
|
||||
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(),
|
||||
@ -590,7 +658,8 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end]]--
|
||||
end]]
|
||||
--
|
||||
-- END OF LISTRING WORKAROUND
|
||||
else
|
||||
return stack:get_count()
|
||||
@ -625,7 +694,8 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
||||
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_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,32 +711,40 @@ 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)..
|
||||
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]"..
|
||||
"listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";input]"..
|
||||
"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]" ..
|
||||
"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("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,
|
||||
@ -681,8 +759,16 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
||||
fixed = { -0.5, -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,
|
||||
groups = {handy=1,axey=1, container=6,not_in_creative_inventory=1, material_wood=1,flammable=-1,double_chest=2},
|
||||
use_texture_alpha = "clip",
|
||||
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(),
|
||||
@ -773,8 +859,10 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
||||
|
||||
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
|
||||
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
|
||||
@ -788,33 +876,40 @@ 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]",
|
||||
|
||||
"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;]",
|
||||
|
||||
"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]"..
|
||||
"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]" ..
|
||||
"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]")
|
||||
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,
|
||||
@ -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,16 +955,20 @@ 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 = {
|
||||
{
|
||||
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")
|
||||
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)
|
||||
@ -868,7 +976,8 @@ register_chest("trapped_chest",
|
||||
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")
|
||||
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")
|
||||
@ -882,17 +991,21 @@ register_chest("trapped_chest",
|
||||
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")
|
||||
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 = {
|
||||
{
|
||||
receptor = {
|
||||
state = mesecon.state.on,
|
||||
rules = trapped_chest_mesecons_rules,
|
||||
}},
|
||||
},
|
||||
},
|
||||
nil, nil, nil,
|
||||
"trapped_chest",
|
||||
"trapped_chest"
|
||||
@ -949,59 +1062,68 @@ minetest.register_craft({
|
||||
{ "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 },
|
||||
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 = {
|
||||
@ -1013,7 +1135,7 @@ minetest.register_node("mcl_chests:ender_chest_small", {
|
||||
_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,
|
||||
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 },
|
||||
@ -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
|
||||
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
|
||||
@ -1070,7 +1195,7 @@ minetest.register_craft({
|
||||
{ "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,8 +1276,10 @@ 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
|
||||
@ -1161,10 +1296,18 @@ for color, desc in pairs(boxtypes) do
|
||||
_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,
|
||||
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,
|
||||
@ -1224,12 +1367,21 @@ for color, desc in pairs(boxtypes) do
|
||||
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,
|
||||
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,
|
||||
@ -1244,7 +1396,8 @@ for color, desc in pairs(boxtypes) do
|
||||
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")
|
||||
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)
|
||||
@ -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
|
||||
@ -1317,14 +1471,16 @@ 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 }
|
||||
recipe = { "group:shulker_box", "mcl_dye:" .. color },
|
||||
})
|
||||
end
|
||||
|
||||
@ -1334,7 +1490,7 @@ minetest.register_craft({
|
||||
{ "mcl_mobitems:shulker_shell" },
|
||||
{ "mcl_chests:chest" },
|
||||
{ "mcl_mobitems:shulker_shell" },
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
-- Save metadata of shulker box when used in crafting
|
||||
@ -1362,7 +1518,8 @@ 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({
|
||||
@ -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
|
||||
@ -1399,7 +1558,8 @@ 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))
|
||||
@ -1408,13 +1568,13 @@ minetest.register_lbm({
|
||||
})
|
||||
|
||||
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,
|
||||
})
|
||||
|
||||
|
@ -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", {
|
||||
@ -57,7 +74,7 @@ minetest.register_craft({
|
||||
recipe = {
|
||||
{ "group:wood", "group:wood" },
|
||||
{ "group:wood", "group:wood" }
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
|
@ -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)
|
||||
@ -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
|
||||
@ -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
|
||||
@ -526,18 +545,44 @@ function mcl_enchanting.show_enchanting_formspec(player)
|
||||
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
|
||||
|
||||
@ -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
|
||||
@ -650,8 +696,10 @@ 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
|
||||
|
@ -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]"..
|
||||
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]"
|
||||
|
||||
"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
|
||||
@ -465,7 +488,8 @@ minetest.register_node("mcl_furnaces:furnace", {
|
||||
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
|
||||
@ -541,7 +565,8 @@ minetest.register_node("mcl_furnaces:furnace_active", {
|
||||
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
|
||||
|
@ -1,31 +1,46 @@
|
||||
-- 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)
|
||||
@ -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)
|
||||
@ -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,
|
||||
|
@ -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]",
|
||||
})
|
||||
|
@ -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,7 +88,6 @@ 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 },
|
||||
|
||||
tiles = {
|
||||
@ -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
|
||||
|
||||
@ -141,5 +163,5 @@ minetest.register_craft({
|
||||
{ "mcl_core:iron_ingot", "mcl_core:iron_ingot", "" },
|
||||
{ "group:wood", "group:wood", "" },
|
||||
{ "group:wood", "group:wood", "" }
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -1,2 +1,2 @@
|
||||
name = mcl_smithing_table
|
||||
depends = mcl_colors, mcl_formspec
|
||||
depends = mcl_colors, mcl_formspec, mcl_anvils
|
||||
|
@ -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]"..
|
||||
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]"
|
||||
|
||||
"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
|
||||
@ -415,7 +438,8 @@ 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" ..
|
||||
@ -442,7 +466,11 @@ minetest.register_node("mcl_smoker:smoker", {
|
||||
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,8 +527,10 @@ 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",
|
||||
@ -519,7 +549,11 @@ minetest.register_node("mcl_smoker:smoker_active", {
|
||||
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
|
||||
|
27
mods/PLAYER/mcl_gamemode/API.md
Normal file
@ -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.
|
84
mods/PLAYER/mcl_gamemode/init.lua
Normal file
@ -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("[<gamemode>] [<player>]"),
|
||||
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
|
||||
})
|
1
mods/PLAYER/mcl_gamemode/mod.conf
Normal file
@ -0,0 +1 @@
|
||||
name = mcl_gamemode
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,3 +1,4 @@
|
||||
local string = string
|
||||
local sf = string.format
|
||||
|
||||
-- Minetest 0.4 mod: player
|
||||
@ -11,7 +12,8 @@ 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
|
||||
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
|
||||
@ -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
|
||||
|
||||
@ -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]
|
||||
@ -166,6 +175,7 @@ minetest.register_on_joinplayer(function(player)
|
||||
mcl_player.player_attached[name] = false
|
||||
player_visible[name] = true
|
||||
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 <https://minecraft.gamepedia.com/Options#Video_settings>>>>
|
||||
end)
|
||||
@ -225,7 +235,9 @@ minetest.register_globalstep(function(dtime)
|
||||
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)
|
||||
|
BIN
textures/crafting_formspec_arrow.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB |
BIN
textures/grindstone_gui_9.png
Normal file
After Width: | Height: | Size: 100 B |
BIN
textures/mcl_anvils_inventory_arrow.png
Normal file
After Width: | Height: | Size: 238 B |
BIN
textures/mcl_anvils_inventory_cross.png
Normal file
After Width: | Height: | Size: 133 B |
BIN
textures/mcl_anvils_inventory_hammer.png
Normal file
After Width: | Height: | Size: 177 B |
BIN
textures/mcl_book_book_empty_slot.png
Normal file
After Width: | Height: | Size: 115 B |
BIN
textures/mcl_inventory_background9.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 240 B After Width: | Height: | Size: 284 B |
Before Width: | Height: | Size: 263 B After Width: | Height: | Size: 298 B |
BIN
textures/mcl_smithing_table_inventory_hammer.png
Normal file
After Width: | Height: | Size: 178 B |
Before Width: | Height: | Size: 241 B After Width: | Height: | Size: 283 B |
Before Width: | Height: | Size: 283 B After Width: | Height: | Size: 320 B |