Auke Kok ba1c93e23f Fix missing tools in tools tab.
Since we converted these tools into craftitems, to allow them to
stack, they have been missing from the tools tab. Explicitly insert
them so builders can obtain them easily again.
2020-03-04 11:19:55 -08:00

274 lines
10 KiB
Lua

--[[
creative - inventory code
Based on `creative` from minetest_game, MIT licensed code.
Original work license:
```
The MIT License (MIT)
Copyright (C) 2012-2016 Perttu Ahola (celeron55) <celeron55@gmail.com>
Copyright (C) 2015-2016 Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com>
```
ITB (insidethebox) minetest game - Copyright (C) 2017-2018 sofar & nore
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation; either version 2.1
of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
]]--
local S = minetest.get_translator("creative")
local FE = minetest.formspec_escape
creative = {}
local player_inventory = {}
local admin = {}
local function creative_allowed(player_name)
return boxes.players_editing_boxes[player_name] or minetest.check_player_privs(player_name, {server = true})
end
function creative.init_creative_inventory(player)
local player_name = player:get_player_name()
player_inventory[player_name] = {
size = 0,
filter = "",
start_i = 0
}
minetest.create_detached_inventory("creative_" .. player_name, {
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player2)
if not player2 or player2:get_player_name() ~= player_name or not creative_allowed(player_name) then
minetest.log("error", "Client accesses inventory illegally (allow_move) (player)")
return 0
end
local stack1 = inv:get_stack(from_list, from_index)
local stack2 = inv:get_stack(to_list, to_index)
if (not stack1 or admin[stack1:get_name()] or not stack2 or admin[stack2:get_name()]) and
not minetest.check_player_privs(player_name, {server = true}) then
minetest.log("error", "Client accesses inventory illegally (allow_move) (privs)")
return 0
end
if not to_list == "main" then
return count
else
minetest.log("error", "Client accesses inventory illegally (allow_move) (list)")
return 0
end
end,
allow_put = function(inv, listname, index, stack, player2)
return 0
end,
allow_take = function(inv, listname, index, stack, player2)
if not player2 or player2:get_player_name() ~= player_name or not creative_allowed(player_name) then
minetest.log("error", "Client accesses inventory illegally (allow_take) (player)")
return 0
end
if (not stack or admin[stack:get_name()]) and
not minetest.check_player_privs(player_name, {server = true}) then
minetest.log("error", "Client accesses inventory illegally (allow_take) (privs)")
return 0
end
return -1
end,
on_move = function(inv, from_list, from_index, to_list, to_index, count, player2)
end,
on_put = function(inv, listname, index, stack, player2)
end,
on_take = function(inv, listname, index, stack, player2)
if stack and stack:get_count() > 0 then
minetest.log("action", player_name .. " takes " .. stack:get_name().. " from creative inventory")
end
end,
}, player_name)
creative.update_creative_inventory(player_name, minetest.registered_items)
end
function creative.update_creative_inventory(player_name, tab_content)
local creative_list = {}
local player_inv = minetest.get_inventory({type = "detached", name = "creative_" .. player_name})
local inv = player_inventory[player_name]
if not inv then
creative.init_creative_inventory(minetest.get_player_by_name(player_name))
end
for name, def in pairs(tab_content) do
if not (def.groups and def.groups.not_in_creative_inventory == 1) and
def.description and def.description ~= "" and
(def.name:find(inv.filter, 1, true) or
def.description:lower():find(inv.filter, 1, true)) then
creative_list[#creative_list+1] = name
end
end
table.sort(creative_list)
player_inv:set_size("main", #creative_list)
player_inv:set_list("main", creative_list)
inv.size = #creative_list
end
-- Create the trash field
local trash = minetest.create_detached_inventory("creative_trash", {
-- Allow the stack to be placed and remove it in on_put()
-- This allows the creative inventory to restore the stack
allow_put = function(inv, listname, index, stack, player)
return stack:get_count()
end,
on_put = function(inv, listname)
inv:set_list(listname, {})
end,
})
trash:set_size("main", 1)
creative.formspec_add = ""
function creative.register_tab(name, title, items)
sfinv.register_page("creative:" .. name, {
title = title,
is_in_nav = function(self, player, context)
if name == "admin" then
return minetest.check_player_privs(player, {server = true})
end
return creative_allowed(player:get_player_name())
end,
get = function(self, player, context)
local player_name = player:get_player_name()
creative.update_creative_inventory(player_name, items)
local inv = player_inventory[player_name]
local start_i = inv.start_i or 0
local pagenum = math.floor(start_i / (3*8) + 1)
local pagemax = math.ceil(inv.size / (3*8))
return sfinv.make_formspec(player, context,
"label[6.2,3.35;" .. minetest.colorize("#FFFF00", tostring(pagenum)) .. " / " .. tostring(pagemax) .. "]" ..
[[
image[4.06,3.4;0.8,0.8;creative_trash_icon.png]
listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]
list[current_player;main;0,4.7;8,1;]
list[current_player;main;0,5.85;8,3;8]
list[detached:creative_trash;main;4,3.3;1,1;]
listring[]
button[5.4,3.2;0.8,0.9;creative_prev;]]..FE(S("<"))..[[]
button[7.25,3.2;0.8,0.9;creative_next;]]..FE(S(">"))..[[]
button[2.1,3.4;0.8,0.5;creative_search;]]..FE(S("?"))..[[]
button[2.75,3.4;0.8,0.5;creative_clear;]]..FE(S("X"))..[[]
tooltip[creative_search;]]..FE(S("Search"))..[[]
tooltip[creative_clear;]]..FE(S("Reset"))..[[]
listring[current_player;main]
field_close_on_enter[creative_filter;false]
]] ..
"field[0.3,3.5;2.2,1;creative_filter;;" .. minetest.formspec_escape(inv.filter) .. "]" ..
"listring[detached:creative_" .. player_name .. ";main]" ..
"list[detached:creative_" .. player_name .. ";main;0,0;8,3;" .. tostring(start_i) .. "]" ..
sfinv.get_hotbar_bg(0,4.7) ..
sfinv.style.gui_bg .. sfinv.style.gui_bg_img .. sfinv.style.gui_slots
.. creative.formspec_add, false)
end,
on_enter = function(self, player, context)
local player_name = player:get_player_name()
local inv = player_inventory[player_name]
if inv then
inv.start_i = 0
end
end,
on_player_receive_fields = function(self, player, context, fields)
local player_name = player:get_player_name()
local inv = player_inventory[player_name]
assert(inv)
if fields.creative_clear then
inv.start_i = 0
inv.filter = ""
creative.update_creative_inventory(player_name, items)
sfinv.set_player_inventory_formspec(player, context)
elseif fields.creative_search or
fields.key_enter_field == "creative_filter" then
inv.start_i = 0
inv.filter = fields.creative_filter:lower()
creative.update_creative_inventory(player_name, items)
sfinv.set_player_inventory_formspec(player, context)
elseif not fields.quit then
local start_i = inv.start_i or 0
if fields.creative_prev then
start_i = start_i - 3*8
if start_i < 0 then
start_i = inv.size - (inv.size % (3*8))
if inv.size == start_i then
start_i = math.max(0, inv.size - (3*8))
end
end
elseif fields.creative_next then
start_i = start_i + 3*8
if start_i >= inv.size then
start_i = 0
end
end
inv.start_i = start_i
sfinv.set_player_inventory_formspec(player, context)
end
end
})
end
minetest.register_on_joinplayer(function(player)
creative.init_creative_inventory(player)
end)
-- custom inventory lists for nodes and tools.
local nodes = table.copy(minetest.registered_nodes)
nodes["boxes:creator_teleport"] = nil
nodes["boxes:enter_teleport"] = nil
nodes["boxes:exit_teleport"] = nil
nodes["boxes:lobby_teleport"] = nil
nodes["nodes:barrier"] = nil
nodes["doors:door_wood"] = table.copy(minetest.registered_items["doors:door_wood"])
nodes["doors:door_wood"].groups = {}
nodes["doors:door_steel"] = table.copy(minetest.registered_items["doors:door_steel"])
nodes["doors:door_steel"].groups = {}
creative.register_tab("nodes", S("Nodes"), nodes)
local tools = table.copy(minetest.registered_tools)
tools["tools:admin"] = nil
tools["inspector:inspector"] = nil
tools["boxes:set_door"] = table.copy(minetest.registered_items["boxes:set_door"])
tools["tools:shovel"] = table.copy(minetest.registered_items["tools:shovel"])
tools["tools:axe"] = table.copy(minetest.registered_items["tools:axe"])
tools["tools:pickaxe"] = table.copy(minetest.registered_items["tools:pickaxe"])
tools["tools:sword"] = table.copy(minetest.registered_items["tools:sword"])
tools["tools:flint_and_steel"] = table.copy(minetest.registered_items["tools:flint_and_steel"])
creative.register_tab("tools", S("Tools"), tools)
admin["boxes:creator_teleport"] = table.copy(minetest.registered_items["boxes:creator_teleport"])
admin["boxes:enter_teleport"] = table.copy(minetest.registered_items["boxes:enter_teleport"])
admin["boxes:exit_teleport"] = table.copy(minetest.registered_items["boxes:exit_teleport"])
admin["boxes:lobby_teleport"] = table.copy(minetest.registered_items["boxes:lobby_teleport"])
admin["nodes:barrier"] = table.copy(minetest.registered_items["nodes:barrier"])
admin["nodes:barrier"].groups = {}
admin["nodes:marbleb"] = table.copy(minetest.registered_items["nodes:marbleb"])
admin["nodes:marbleb"].groups = {}
admin["nodes:bronzeb"] = table.copy(minetest.registered_items["nodes:bronzeb"])
admin["nodes:bronzeb"].groups = {}
admin["tools:admin"] = table.copy(minetest.registered_items["tools:admin"])
admin["inspector:inspector"] = table.copy(minetest.registered_items["inspector:inspector"])
admin["boxes:nexus_large"] = table.copy(minetest.registered_items["boxes:nexus_large"])
admin["boxes:nexus_large"].groups = {}
creative.register_tab("admin", S("Admin Items"), admin)