mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-08-26 03:47:25 +02:00
Before this patch it was possible for any user to to crash Minetest in creative mode. This was possible because queries in the search field were interpreted as search patterns for string.find(). A search for a single square bracket would reliably crash the server. Also, a search for 6000 times the string “a?” would hang the server. The solution to both bugs is to not interpret the query as a pattern.
712 lines
22 KiB
Lua
712 lines
22 KiB
Lua
local S = minetest.get_translator(minetest.get_current_modname())
|
|
local F = minetest.formspec_escape
|
|
local C = minetest.colorize
|
|
|
|
-- Prepare player info table
|
|
local players = {}
|
|
|
|
-- Containing all the items for each Creative Mode tab
|
|
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"}
|
|
for _, f in pairs(builtin_filter_ids) do
|
|
inventory_lists[f] = {}
|
|
end
|
|
|
|
local function replace_enchanted_books(tbl)
|
|
for k, item in ipairs(tbl) do
|
|
if item:find("mcl_enchanting:book_enchanted") == 1 then
|
|
local _, enchantment, level = item:match("(%a+) ([_%w]+) (%d+)")
|
|
level = level and tonumber(level)
|
|
if enchantment and level then
|
|
tbl[k] = mcl_enchanting.enchant(ItemStack("mcl_enchanting:book_enchanted"), enchantment, level)
|
|
end
|
|
end
|
|
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. ]]
|
|
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
|
|
local function is_redstone(def)
|
|
return def.mesecons or def.groups.mesecon or def.groups.mesecon_conductor_craftable or def.groups.mesecon_effecor_off
|
|
end
|
|
local function is_tool(def)
|
|
return def.groups.tool or (def.tool_capabilities and def.tool_capabilities.damage_groups == nil)
|
|
end
|
|
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)
|
|
end
|
|
-- Is set to true if it was added in any category besides misc
|
|
local nonmisc = false
|
|
if def.groups.building_block then
|
|
table.insert(inventory_lists["blocks"], name)
|
|
nonmisc = true
|
|
end
|
|
if def.groups.deco_block then
|
|
table.insert(inventory_lists["deco"], name)
|
|
nonmisc = true
|
|
end
|
|
if is_redstone(def) then
|
|
table.insert(inventory_lists["redstone"], name)
|
|
nonmisc = true
|
|
end
|
|
if def.groups.transport then
|
|
table.insert(inventory_lists["rail"], name)
|
|
nonmisc = true
|
|
end
|
|
if (def.groups.food and not def.groups.brewitem) or def.groups.eatable then
|
|
table.insert(inventory_lists["food"], name)
|
|
nonmisc = true
|
|
end
|
|
if is_tool(def) then
|
|
table.insert(inventory_lists["tools"], name)
|
|
nonmisc = true
|
|
end
|
|
if is_weapon_or_armor(def) then
|
|
table.insert(inventory_lists["combat"], name)
|
|
nonmisc = true
|
|
end
|
|
if def.groups.spawn_egg == 1 then
|
|
table.insert(inventory_lists["mobs"], name)
|
|
nonmisc = true
|
|
end
|
|
if def.groups.brewitem then
|
|
table.insert(inventory_lists["brew"], name)
|
|
nonmisc = true
|
|
end
|
|
if def.groups.craftitem then
|
|
table.insert(inventory_lists["matr"], name)
|
|
nonmisc = true
|
|
end
|
|
-- Misc. category is for everything which is not in any other category
|
|
if not nonmisc then
|
|
table.insert(inventory_lists["misc"], name)
|
|
end
|
|
|
|
table.insert(inventory_lists["all"], name)
|
|
end
|
|
end
|
|
|
|
for ench, def in pairs(mcl_enchanting.enchantments) do
|
|
local str = "mcl_enchanting:book_enchanted " .. ench .. " " .. def.max_level
|
|
if def.inv_tool_tab then
|
|
table.insert(inventory_lists["tools"], str)
|
|
end
|
|
if def.inv_combat_tab then
|
|
table.insert(inventory_lists["combat"], str)
|
|
end
|
|
table.insert(inventory_lists["all"], str)
|
|
end
|
|
|
|
for _, to_sort in pairs(inventory_lists) do
|
|
table.sort(to_sort)
|
|
replace_enchanted_books(to_sort)
|
|
end
|
|
end)
|
|
|
|
local function filter_item(name, description, lang, filter)
|
|
local desc
|
|
if not lang then
|
|
desc = string.lower(description)
|
|
else
|
|
desc = string.lower(minetest.get_translated_string(lang, description))
|
|
end
|
|
return string.find(name, filter, nil, true) or string.find(desc, filter, nil, true)
|
|
end
|
|
|
|
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 filter_item(string.lower(def.name), def.description, lang, filter) then
|
|
table.insert(creative_list, name)
|
|
end
|
|
end
|
|
end
|
|
for ench, def in pairs(mcl_enchanting.enchantments) do
|
|
for i = 1, def.max_level do
|
|
local stack = mcl_enchanting.enchant(ItemStack("mcl_enchanting:book_enchanted"), ench, i)
|
|
if filter_item("mcl_enchanting:book_enchanted", minetest.strip_colors(stack:get_description()), lang, filter) then
|
|
table.insert(creative_list, "mcl_enchanting:book_enchanted " .. ench .. " " .. i)
|
|
end
|
|
end
|
|
end
|
|
table.sort(creative_list)
|
|
replace_enchanted_books(creative_list)
|
|
|
|
inv:set_size("main", #creative_list)
|
|
inv:set_list("main", creative_list)
|
|
end
|
|
|
|
local function set_inv_page(page, player)
|
|
local playername = player:get_player_name()
|
|
local inv = minetest.get_inventory({type="detached", name="creative_"..playername})
|
|
inv:set_size("main", 0)
|
|
local creative_list = {}
|
|
if inventory_lists[page] then -- Standard filter
|
|
creative_list = inventory_lists[page]
|
|
end
|
|
inv:set_size("main", #creative_list)
|
|
inv:set_list("main", creative_list)
|
|
end
|
|
|
|
local function init(player)
|
|
local playername = player:get_player_name()
|
|
minetest.create_detached_inventory("creative_"..playername, {
|
|
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
|
if minetest.is_creative_enabled(playername) then
|
|
return count
|
|
else
|
|
return 0
|
|
end
|
|
end,
|
|
allow_put = function(inv, listname, index, stack, player)
|
|
return 0
|
|
end,
|
|
allow_take = function(inv, listname, index, stack, player)
|
|
if minetest.is_creative_enabled(player:get_player_name()) then
|
|
return -1
|
|
else
|
|
return 0
|
|
end
|
|
end,
|
|
}, playername)
|
|
set_inv_page("all", player)
|
|
end
|
|
|
|
-- Create the trash field
|
|
local trash = minetest.create_detached_inventory("trash", {
|
|
allow_put = function(inv, listname, index, stack, player)
|
|
if minetest.is_creative_enabled(player:get_player_name()) then
|
|
return stack:get_count()
|
|
else
|
|
return 0
|
|
end
|
|
end,
|
|
on_put = function(inv, listname, index, stack, player)
|
|
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 = {}
|
|
|
|
local noffset_x_start = -0.24
|
|
local noffset_x = noffset_x_start
|
|
local noffset_y = -0.25
|
|
local function next_noffset(id, right)
|
|
if right then
|
|
noffset[id] = { 8.94, noffset_y }
|
|
else
|
|
noffset[id] = { noffset_x, noffset_y }
|
|
noffset_x = noffset_x + 1.25
|
|
end
|
|
end
|
|
|
|
-- Upper row
|
|
next_noffset("blocks")
|
|
next_noffset("deco")
|
|
next_noffset("redstone")
|
|
next_noffset("rail")
|
|
next_noffset("brew")
|
|
next_noffset("misc")
|
|
next_noffset("nix", true)
|
|
|
|
noffset_x = noffset_x_start
|
|
noffset_y = 8.12
|
|
|
|
-- Lower row
|
|
next_noffset("food")
|
|
next_noffset("tools")
|
|
next_noffset("combat")
|
|
next_noffset("mobs")
|
|
next_noffset("matr")
|
|
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)
|
|
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"
|
|
|
|
filtername["blocks"] = S("Building Blocks")
|
|
filtername["deco"] = S("Decoration Blocks")
|
|
filtername["redstone"] = S("Redstone")
|
|
filtername["rail"] = S("Transportation")
|
|
filtername["misc"] = S("Miscellaneous")
|
|
filtername["nix"] = S("Search Items")
|
|
filtername["food"] = S("Foodstuffs")
|
|
filtername["tools"] = S("Tools")
|
|
filtername["combat"] = S("Combat")
|
|
filtername["mobs"] = S("Mobs")
|
|
filtername["brew"] = S("Brewing")
|
|
filtername["matr"] = S("Materials")
|
|
filtername["inv"] = S("Survival Inventory")
|
|
|
|
--local dark_bg = "crafting_creative_bg_dark.png"
|
|
|
|
--[[local function reset_menu_item_bg()
|
|
bg["blocks"] = dark_bg
|
|
bg["deco"] = dark_bg
|
|
bg["redstone"] = dark_bg
|
|
bg["rail"] = dark_bg
|
|
bg["misc"] = dark_bg
|
|
bg["nix"] = dark_bg
|
|
bg["food"] = dark_bg
|
|
bg["tools"] = dark_bg
|
|
bg["combat"] = dark_bg
|
|
bg["mobs"] = dark_bg
|
|
bg["brew"] = dark_bg
|
|
bg["matr"] = dark_bg
|
|
bg["inv"] = dark_bg
|
|
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, start_i, pagenum, inv_size, show, page, filter)
|
|
--reset_menu_item_bg()
|
|
pagenum = math.floor(pagenum) or 1
|
|
|
|
local playername = player:get_player_name()
|
|
|
|
if not inv_size then
|
|
if page == "nix" then
|
|
local inv = minetest.get_inventory({type="detached", name="creative_"..playername})
|
|
inv_size = inv:get_size("main")
|
|
elseif page and page ~= "inv" then
|
|
inv_size = #(inventory_lists[page])
|
|
else
|
|
inv_size = 0
|
|
end
|
|
end
|
|
local pagemax = math.max(1, math.floor((inv_size-1) / (9*5) + 1))
|
|
local name = "nix"
|
|
local main_list
|
|
local listrings = "listring[detached:creative_"..playername..";main]"..
|
|
"listring[current_player;main]"..
|
|
"listring[detached:trash;main]"
|
|
|
|
if page then
|
|
name = page
|
|
if players[playername] then
|
|
players[playername].page = page
|
|
end
|
|
end
|
|
--bg[name] = "crafting_creative_bg.png"
|
|
|
|
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
|
|
|
|
local tab_icon = {
|
|
blocks = "mcl_core:brick_block",
|
|
deco = "mcl_flowers:peony",
|
|
redstone = "mesecons:redstone",
|
|
rail = "mcl_minecarts:golden_rail",
|
|
misc = "mcl_buckets:bucket_lava",
|
|
nix = "mcl_compass:compass",
|
|
food = "mcl_core:apple",
|
|
tools = "mcl_core:axe_iron",
|
|
combat = "mcl_core:sword_gold",
|
|
mobs = "mobs_mc:cow",
|
|
brew = "mcl_potions:dragon_breath",
|
|
matr = "mcl_core:stick",
|
|
inv = "mcl_chests:chest",
|
|
}
|
|
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"
|
|
else
|
|
bg_img = "crafting_creative_inactive"..hoch[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 .. "]"
|
|
end
|
|
local caption = ""
|
|
if name ~= "inv" and filtername[name] then
|
|
caption = "label[0,1.2;"..F(minetest.colorize("#313131", 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
|
|
|
|
if name == "nix" then
|
|
if filter == nil then
|
|
filter = ""
|
|
end
|
|
formspec = formspec .. "field[5.3,1.34;4,0.75;search;;"..minetest.formspec_escape(filter).."]"
|
|
formspec = formspec .. "field_close_on_enter[search;false]"
|
|
end
|
|
if pagenum then formspec = formspec .. "p"..tostring(pagenum) end
|
|
player:set_inventory_formspec(formspec)
|
|
end
|
|
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
local page = nil
|
|
|
|
if not minetest.is_creative_enabled(player:get_player_name()) then
|
|
return
|
|
end
|
|
if formname ~= "" or fields.quit == "true" then
|
|
-- No-op if formspec closed or not player inventory (formname == "")
|
|
return
|
|
end
|
|
|
|
local name = player:get_player_name()
|
|
|
|
if fields.blocks then
|
|
if players[name].page == "blocks" then return end
|
|
set_inv_page("blocks",player)
|
|
page = "blocks"
|
|
elseif fields.deco then
|
|
if players[name].page == "deco" then return end
|
|
set_inv_page("deco",player)
|
|
page = "deco"
|
|
elseif fields.redstone then
|
|
if players[name].page == "redstone" then return end
|
|
set_inv_page("redstone",player)
|
|
page = "redstone"
|
|
elseif fields.rail then
|
|
if players[name].page == "rail" then return end
|
|
set_inv_page("rail",player)
|
|
page = "rail"
|
|
elseif fields.misc then
|
|
if players[name].page == "misc" then return end
|
|
set_inv_page("misc",player)
|
|
page = "misc"
|
|
elseif fields.nix then
|
|
set_inv_page("all",player)
|
|
page = "nix"
|
|
elseif fields.food then
|
|
if players[name].page == "food" then return end
|
|
set_inv_page("food",player)
|
|
page = "food"
|
|
elseif fields.tools then
|
|
if players[name].page == "tools" then return end
|
|
set_inv_page("tools",player)
|
|
page = "tools"
|
|
elseif fields.combat then
|
|
if players[name].page == "combat" then return end
|
|
set_inv_page("combat",player)
|
|
page = "combat"
|
|
elseif fields.mobs then
|
|
if players[name].page == "mobs" then return end
|
|
set_inv_page("mobs",player)
|
|
page = "mobs"
|
|
elseif fields.brew then
|
|
if players[name].page == "brew" then return end
|
|
set_inv_page("brew",player)
|
|
page = "brew"
|
|
elseif fields.matr then
|
|
if players[name].page == "matr" then return end
|
|
set_inv_page("matr",player)
|
|
page = "matr"
|
|
elseif fields.inv then
|
|
if players[name].page == "inv" then return end
|
|
page = "inv"
|
|
elseif fields.search == "" and not fields.creative_next and not fields.creative_prev then
|
|
set_inv_page("all", player)
|
|
page = "nix"
|
|
elseif fields.search and not fields.creative_next and not fields.creative_prev then
|
|
set_inv_search(string.lower(fields.search),player)
|
|
page = "nix"
|
|
elseif fields.__switch_stack then
|
|
local switch = 1
|
|
if get_stack_size(player) == 1 then
|
|
switch = 64
|
|
end
|
|
set_stack_size(player, switch)
|
|
end
|
|
|
|
if page then
|
|
players[name].page = page
|
|
end
|
|
if players[name].page then
|
|
page = players[name].page
|
|
end
|
|
|
|
-- Figure out current scroll bar from formspec
|
|
--local formspec = player:get_inventory_formspec()
|
|
|
|
local start_i = players[name].start_i
|
|
|
|
if fields.creative_prev then
|
|
start_i = start_i - 9*5
|
|
elseif fields.creative_next then
|
|
start_i = start_i + 9*5
|
|
else
|
|
-- Reset scroll bar if not scrolled
|
|
start_i = 0
|
|
end
|
|
if start_i < 0 then
|
|
start_i = start_i + 9*5
|
|
end
|
|
|
|
local inv_size
|
|
if page == "nix" then
|
|
local inv = minetest.get_inventory({type="detached", name="creative_"..name})
|
|
inv_size = inv:get_size("main")
|
|
elseif page and page ~= "inv" then
|
|
inv_size = #(inventory_lists[page])
|
|
else
|
|
inv_size = 0
|
|
end
|
|
|
|
if start_i >= inv_size then
|
|
start_i = start_i - 9*5
|
|
end
|
|
if start_i < 0 or start_i >= inv_size then
|
|
start_i = 0
|
|
end
|
|
players[name].start_i = start_i
|
|
|
|
local filter = ""
|
|
if not fields.nix and fields.search and fields.search ~= "" then
|
|
filter = fields.search
|
|
players[name].filter = filter
|
|
end
|
|
|
|
mcl_inventory.set_creative_formspec(player, start_i, start_i / (9*5) + 1, inv_size, false, page, filter)
|
|
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
|
|
|
|
mcl_inventory.update_inventory_formspec = function(player)
|
|
local page
|
|
|
|
local name = player:get_player_name()
|
|
|
|
if players[name].page then
|
|
page = players[name].page
|
|
else
|
|
page = "nix"
|
|
end
|
|
|
|
-- Figure out current scroll bar from formspec
|
|
--local formspec = player:get_inventory_formspec()
|
|
local start_i = players[name].start_i
|
|
|
|
local inv_size
|
|
if page == "nix" then
|
|
local inv = minetest.get_inventory({type="detached", name="creative_"..name})
|
|
inv_size = inv:get_size("main")
|
|
elseif page and page ~= "inv" then
|
|
inv_size = #(inventory_lists[page])
|
|
else
|
|
inv_size = 0
|
|
end
|
|
|
|
local filter = players[name].filter
|
|
if filter == nil then
|
|
filter = ""
|
|
end
|
|
|
|
mcl_inventory.set_creative_formspec(player, start_i, start_i / (9*5) + 1, inv_size, false, page, filter)
|
|
end
|
|
end
|
|
|
|
minetest.register_on_joinplayer(function(player)
|
|
-- Initialize variables and inventory
|
|
local name = player:get_player_name()
|
|
if not players[name] then
|
|
players[name] = {}
|
|
players[name].page = "nix"
|
|
players[name].filter = ""
|
|
players[name].start_i = 0
|
|
end
|
|
init(player)
|
|
mcl_inventory.set_creative_formspec(player, 0, 1, nil, false, "nix", "")
|
|
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
|
|
local stack = inventory_info.stack
|
|
stack:set_count(stack:get_stack_max())
|
|
player:get_inventory():set_stack("main", inventory_info.index, stack)
|
|
end
|
|
end)
|