updated upgraded simplified creative and provide privilegie feature

* register privilegie of creative for older or newer engines
* enhanced the formspec of the creative player to 4 rows
* try to upgrade most close to track upstream original
* return back text button, remove extra media
  check https://notabug.org/TenPlus1/creative/issues/2
* update readme information to diference features
This commit is contained in:
mckaygerhard 2023-06-16 00:36:33 -04:00
parent ae8c3f8eba
commit f208b6312d
5 changed files with 250 additions and 84 deletions

View File

@ -1,13 +1,14 @@
Minetest Game mod: creative Minetest Game mod: creative
=========================== ===========================
Simplified creative with faster loading Simplified creative for more accurate on mobile or small screens
Information Information
------------ ------------
This mod is named `creative` and is a replacement for default "creative" mod This mod is named `creative` and is a replacement for default "creative" mod
of orginal game, with reduced tabs, also it uses a cached memory to faster lodaing. of orginal game, with reduced tabs, also minenux fork it uses a cached memory and no images
to faster lodaing respect settings.
![screenshot.png](screenshot.png) ![screenshot.png](screenshot.png)
@ -19,9 +20,19 @@ for backguard compatibility with 5.2 and 0.4.16, with minimal backports, you
can download from https://codeberg.org/minenux/minetest-mod-creative and after can download from https://codeberg.org/minenux/minetest-mod-creative and after
clone or downloaded renamed to `creative` (obviously replace the current one if any) clone or downloaded renamed to `creative` (obviously replace the current one if any)
Modified by TenPlus1 (added creative privelage, reduced tab count, tweaked code), Modified by TenPlus1 (added creative privilege, reduced tab count, tweaked code),
original work is at https://notabug.org/TenPlus1/creative original work is at https://notabug.org/TenPlus1/creative
The minenux fork cut down images to use only text so media download is not a hit!
#### Api
You can use `creative.is_creative(playername)` (older) or `creative.is_enabled_for(playername)`.
#### Dependencies
* sfinv
### Authors of source code ### Authors of source code
Originally by Perttu Ahola (celeron55) <celeron55@gmail.com> (MIT) Originally by Perttu Ahola (celeron55) <celeron55@gmail.com> (MIT)

View File

@ -1,13 +1,14 @@
Minetest Game mod: creative Minetest Game mod: creative
=========================== ===========================
Simplified creative with faster loading Simplified creative for more accurate on mobile or small screens
Information Information
------------ ------------
This mod is named `creative` and is a replacement for default "creative" mod This mod is named `creative` and is a replacement for default "creative" mod
of orginal game, with reduced tabs, also it uses a cached memory to faster lodaing. of orginal game, with reduced tabs, also minenux fork it uses a cached memory
to faster lodaing respect settings.
![screenshot.png](screenshot.png) ![screenshot.png](screenshot.png)
@ -19,9 +20,11 @@ for backguard compatibility with 5.2 and 0.4.16, with minimal backports, you
can download from https://codeberg.org/minenux/minetest-mod-creative and after can download from https://codeberg.org/minenux/minetest-mod-creative and after
clone or downloaded renamed to `creative` (obviously replace the current one if any) clone or downloaded renamed to `creative` (obviously replace the current one if any)
Modified by TenPlus1 (added creative privelage, reduced tab count, tweaked code), Modified by TenPlus1 (added creative privilege, reduced tab count, tweaked code),
original work is at https://notabug.org/TenPlus1/creative original work is at https://notabug.org/TenPlus1/creative
The minenux fork cut down images to use only text so media download is not a hit!
### Authors of source code ### Authors of source code
Originally by Perttu Ahola (celeron55) <celeron55@gmail.com> (MIT) Originally by Perttu Ahola (celeron55) <celeron55@gmail.com> (MIT)
@ -29,7 +32,7 @@ Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com> (MIT)
### Author of media (textures) ### Author of media (textures)
Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com> (CC BY-SA 3.0) Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com> (CC-BY-SA 3.0)
LICENSE LICENSE
------- -------

View File

@ -1 +1 @@
Simplified creative with faster loading Simplified creative for more accurate on mobile or small screens

View File

@ -1,21 +1,80 @@
creative = {}
minetest.register_privilege("creative", { -- Load support for MT game translation.
description = "Allow player to use creative inventory", local S
give_to_singleplayer = false,
give_to_admin = false,
on_grant = update_sfinv,
on_revoke = update_sfinv,
})
if minetest.get_translator ~= nil then
S = minetest.get_translator("creative") -- 5.x translation function
else
if minetest.get_modpath("intllib") then
dofile(minetest.get_modpath("intllib") .. "/init.lua")
if intllib.make_gettext_pair then
S = intllib.make_gettext_pair() -- new gettext method
else
S = intllib.Getter() -- old text file method
end
else -- boilerplate function
S = function(str, ...)
local args = {...}
return str:gsub("@%d+", function(match)
return args[tonumber(match:sub(2))]
end)
end
end
end
local is_50 = minetest.has_feature("object_use_texture_alpha")
local is_53 = minetest.has_feature("object_step_has_moveresult") local is_53 = minetest.has_feature("object_step_has_moveresult")
local is_54 = minetest.has_feature("direct_velocity_on_players")
creative = {}
creative.get_translator = S
creative.is_50 = is_50
creative.is_53 = is_53
creative.is_54 = is_54
local privs_description = "Allow player to use creative inventory"
local privs_definition = {}
local function update_sfinv(name)
minetest.after(0, function()
local player = minetest.get_player_by_name(name)
if player then
if sfinv.get_page(player):sub(1, 9) == "creative:" then
sfinv.set_page(player, sfinv.get_homepage_name(player))
else
sfinv.set_player_inventory_formspec(player)
end
end
end)
end
if is_50 then
privs_definition = {
description = privs_description,
give_to_singleplayer = false,
give_to_admin = false,
on_grant = update_sfinv,
on_revoke = update_sfinv
}
else
privs_definition = {
description = privs_description,
give_to_singleplayer = false
}
end
minetest.register_privilege("creative", privs_definition)
local creative_mode_cache = minetest.settings:get_bool("creative_mode") local creative_mode_cache = minetest.settings:get_bool("creative_mode")
-- backguard compatibility -- backguard compatibility
function creative.is_creative(name) function creative.is_creative(name)
if is_53 then if creative.is_53 then
return minetest.is_creative_enabled(name) if name == "" then
return minetest.is_creative_enabled(name)
else
return minetest.check_player_privs(name, {creative = true}) or creative_mode_cache
end
else else
return minetest.check_player_privs(name, {creative = true}) or creative_mode_cache return minetest.check_player_privs(name, {creative = true}) or creative_mode_cache
end end
@ -57,7 +116,9 @@ function creative.init_creative_inventory(player)
player_inventory[player_name] = { player_inventory[player_name] = {
size = 0, size = 0,
filter = "", filter = "",
start_i = 0 start_i = 0,
old_filter = nil, -- use only for caching in update_creative_inventory
old_content = nil
} }
minetest.create_detached_inventory("creative_" .. player_name, { minetest.create_detached_inventory("creative_" .. player_name, {
@ -91,29 +152,76 @@ function creative.init_creative_inventory(player)
return player_inventory[player_name] return player_inventory[player_name]
end end
local NO_MATCH = 999
local function match(s, filter)
if filter == "" then
return 0
end
if s:lower():find(filter, 1, true) then
return #s - #filter
end
return NO_MATCH
end
local function description(def, lang_code)
local s = def.description
if creative.is_53 then
if lang_code then
s = minetest.get_translated_string(lang_code, s)
end
end
return s:gsub("\n.*", "") -- First line only
end
function creative.update_creative_inventory(player_name, tab_content) function creative.update_creative_inventory(player_name, tab_content)
local creative_list = {}
local inv = player_inventory[player_name] or local inv = player_inventory[player_name] or
creative.init_creative_inventory(minetest.get_player_by_name(player_name)) creative.init_creative_inventory(minetest.get_player_by_name(player_name))
local player_inv = minetest.get_inventory({type = "detached", name = "creative_" .. player_name}) local player_inv = minetest.get_inventory({type = "detached", name = "creative_" .. player_name})
if inv.filter == inv.old_filter and tab_content == inv.old_content then
return
end
inv.old_filter = inv.filter
inv.old_content = tab_content
local items = inventory_cache[tab_content] or init_creative_cache(tab_content) local items = inventory_cache[tab_content] or init_creative_cache(tab_content)
for name, def in pairs(items) do local lang = minetest.settings:get("language") or "en"
if def.name:find(inv.filter, 1, true) or local player_info = minetest.get_player_information(player_name)
def.description:lower():find(inv.filter, 1, true) then
creative_list[#creative_list+1] = name if is_53 then
if player_info and player_info.lang_code ~= "" then
lang = player_info.lang_code
end end
end end
table.sort(creative_list) local creative_list = {}
local order = {}
for name, def in pairs(items) do
local m = match(description(def), inv.filter)
if m > 0 then
m = math.min(m, match(description(def, lang), inv.filter))
end
if m > 0 then
m = math.min(m, match(name, inv.filter))
end
if m < NO_MATCH then
creative_list[#creative_list+1] = name
-- Sort by match value first so closer matches appear earlier
order[name] = string.format("%02d", m) .. name
end
end
table.sort(creative_list, function(a, b) return order[a] < order[b] end)
player_inv:set_size("main", #creative_list) player_inv:set_size("main", #creative_list)
player_inv:set_list("main", creative_list) player_inv:set_list("main", creative_list)
inv.size = #creative_list inv.size = #creative_list
end end
-- Create the trash field -- Create the trash field
local trash = minetest.create_detached_inventory("creative_trash", { local trash = minetest.create_detached_inventory("trash", {
-- Allow the stack to be placed and remove it in on_put() -- Allow the stack to be placed and remove it in on_put()
-- This allows the creative inventory to restore the stack -- This allows the creative inventory to restore the stack
allow_put = function(inv, listname, index, stack, player) allow_put = function(inv, listname, index, stack, player)
@ -138,35 +246,33 @@ function creative.register_tab(name, title, items)
creative.update_creative_inventory(player_name, items) creative.update_creative_inventory(player_name, items)
local inv = player_inventory[player_name] local inv = player_inventory[player_name]
local start_i = inv.start_i or 0 local start_i = inv.start_i or 0
local pagenum = math.floor(start_i / (3*8) + 1) local pagenum = math.floor(inv.start_i / (4*8) + 1)
local pagemax = math.ceil(inv.size / (3*8)) local pagemax = math.max(math.ceil(inv.size / (4*8)), 1)
local esc = minetest.formspec_escape
return sfinv.make_formspec(player, context, return sfinv.make_formspec(player, context,
"label[6.2,3.35;" .. minetest.colorize("#FFFF00", tostring(pagenum)) .. " / " .. tostring(pagemax) .. "]" .. (inv.size == 0 and ("label[3,2;>_<]") or "") ..
"label[5.8,4.15;" .. minetest.colorize("#FFFF00", tostring(pagenum)) .. " / " .. tostring(pagemax) .. "]" ..
[[ [[
image[4.06,3.4;0.8,0.8;creative_trash_icon.png] image[4,3.9;0.8,0.8;creative_trash_icon.png]
listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF] listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]
list[current_player;main;0,4.7;8,1;] list[current_player;main;0,4.7;8,1;]
list[current_player;main;0,5.85;8,3;8] list[current_player;main;0,5.85;8,3;8]
list[detached:creative_trash;main;4,3.3;1,1;] list[detached:trash;main;4,3.9;1,1;]
listring[] listring[]
button[5.4,3.2;0.8,0.9;creative_prev;<] button[5,4.05;0.8,0.8;creative_prev;<]
button[7.25,3.2;0.8,0.9;creative_next;>] button[7.25,4.05;0.8,0.8;creative_next;>]
button[2.1,3.4;0.8,0.5;creative_search;?] button[2.63,4.05;0.8,0.8;creative_search;?]
button[2.75,3.4;0.8,0.5;creative_clear;X] button[3.25,4.05;0.8,0.8;creative_clear;X]
-- image_button[5.4,3.25;0.8,0.8;creative_prev_icon.png;creative_prev;]
-- image_button[7.2,3.25;0.8,0.8;creative_next_icon.png;creative_next;]
-- image_button[2.1,3.25;0.8,0.8;creative_search_icon.png;creative_search;]
-- image_button[2.75,3.25;0.8,0.8;creative_clear_icon.png;creative_clear;]
tooltip[creative_search;Search]
tooltip[creative_clear;Reset]
tooltip[creative_prev;Previous page]
tooltip[creative_next;Next page]
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) .. "]" .. "tooltip[creative_search;" .. esc(S("Search")) .. "]" ..
"tooltip[creative_clear;" .. esc(S("Reset")) .. "]" ..
"tooltip[creative_prev;" .. esc(S("Previous page")) .. "]" ..
"tooltip[creative_next;" .. esc(S("Next page")) .. "]" ..
"listring[current_player;main]" ..
"field_close_on_enter[creative_filter;false]" ..
"field[0.3,4.2;2.8,1.2;creative_filter;;" .. esc(inv.filter) .. "]" ..
"listring[detached:creative_" .. player_name .. ";main]" .. "listring[detached:creative_" .. player_name .. ";main]" ..
"list[detached:creative_" .. player_name .. ";main;0,0;8,3;" .. tostring(start_i) .. "]" .. "list[detached:creative_" .. player_name .. ";main;0,0;8,4;" .. tostring(inv.start_i) .. "]" ..
default.get_hotbar_bg(0,4.7) .. default.get_hotbar_bg(0,4.7) ..
default.gui_bg .. default.gui_bg_img .. default.gui_slots default.gui_bg .. default.gui_bg_img .. default.gui_slots
.. creative.formspec_add, false) .. creative.formspec_add, false)
@ -186,27 +292,30 @@ function creative.register_tab(name, title, items)
if fields.creative_clear then if fields.creative_clear then
inv.start_i = 0 inv.start_i = 0
inv.filter = "" inv.filter = ""
creative.update_creative_inventory(player_name, items) --creative.update_creative_inventory(player_name, items)
sfinv.set_player_inventory_formspec(player, context) sfinv.set_player_inventory_formspec(player, context)
elseif fields.creative_search or elseif (fields.creative_search or
fields.key_enter_field == "creative_filter" then fields.key_enter_field == "creative_filter")
and fields.creative_filter then
inv.start_i = 0 inv.start_i = 0
inv.filter = fields.creative_filter:lower() inv.filter = fields.creative_filter:sub(1, 128) -- truncate to a sane length
creative.update_creative_inventory(player_name, items) :gsub("[%z\1-\8\11-\31\127]", "") -- strip naughty control characters (keeps \t and \n)
:lower() -- search is case insensitive
--creative.update_creative_inventory(player_name, items)
sfinv.set_player_inventory_formspec(player, context) sfinv.set_player_inventory_formspec(player, context)
elseif not fields.quit then elseif not fields.quit then
local start_i = inv.start_i or 0 local start_i = inv.start_i or 0
if fields.creative_prev then if fields.creative_prev then
start_i = start_i - 3*8 start_i = start_i - 4*8
if start_i < 0 then if start_i < 0 then
start_i = inv.size - (inv.size % (3*8)) start_i = inv.size - (inv.size % (4*8))
if inv.size == start_i then if inv.size == start_i then
start_i = math.max(0, inv.size - (3*8)) start_i = math.max(0, inv.size - (4*8))
end end
end end
elseif fields.creative_next then elseif fields.creative_next then
start_i = start_i + 3*8 start_i = start_i + 4*8
if start_i >= inv.size then if start_i >= inv.size then
start_i = 0 start_i = 0
end end
@ -219,11 +328,36 @@ function creative.register_tab(name, title, items)
}) })
end end
--creative.register_tab("all", "Creative", minetest.registered_items) -- Sort registered items
creative.register_tab("all", "All", minetest.registered_items) local registered_nodes = {}
creative.register_tab("nodes", "Nodes", minetest.registered_nodes) local registered_tools = {}
creative.register_tab("tools", "Tools", minetest.registered_tools) local registered_craftitems = {}
creative.register_tab("craftitems", "Items", minetest.registered_craftitems)
local tab_items = function()
for name, def in pairs(minetest.registered_items) do
local group = def.groups or {}
local nogroup = not (group.node or group.tool or group.craftitem)
if group.node or (nogroup and minetest.registered_nodes[name]) then
registered_nodes[name] = def
elseif group.tool or (nogroup and minetest.registered_tools[name]) then
registered_tools[name] = def
elseif group.craftitem or (nogroup and minetest.registered_craftitems[name]) then
registered_craftitems[name] = def
end
end
end
if minetest.register_on_mods_loaded then
minetest.register_on_mods_loaded(tab_items)
else
minetest.after(0.1, tab_items)
end
creative.register_tab("all", S("All"), minetest.registered_items)
creative.register_tab("nodes", S("Nodes"), minetest.registered_nodes)
creative.register_tab("tools", S("Tools"), minetest.registered_tools)
creative.register_tab("craftitems", S("Items"), minetest.registered_craftitems)
local old_homepage_name = sfinv.get_homepage_name local old_homepage_name = sfinv.get_homepage_name
function sfinv.get_homepage_name(player) function sfinv.get_homepage_name(player)
@ -235,13 +369,14 @@ function sfinv.get_homepage_name(player)
end end
if creative_mode_cache then if minetest.is_creative_enabled("") then
-- Dig time is modified according to difference (leveldiff) between tool local hand_hack = function()
-- 'maxlevel' and node 'level'. Digtime is divided by the larger of -- Dig time is modified according to difference (leveldiff) between tool
-- leveldiff and 1. -- 'maxlevel' and node 'level'. Digtime is divided by the larger of
-- To speed up digging in creative, hand 'maxlevel' and 'digtime' have been -- leveldiff and 1.
-- increased such that nodes of differing levels have an insignificant -- To speed up digging in creative, hand 'maxlevel' and 'digtime' have been
-- effect on digtime. -- increased such that nodes of differing levels have an insignificant
-- effect on digtime.
local digtime = 42 local digtime = 42
local caps = {times = {digtime, digtime, digtime}, uses = 0, maxlevel = 256} local caps = {times = {digtime, digtime, digtime}, uses = 0, maxlevel = 256}
@ -259,33 +394,50 @@ if creative_mode_cache then
snappy = caps, snappy = caps,
choppy = caps, choppy = caps,
oddly_breakable_by_hand = caps, oddly_breakable_by_hand = caps,
-- dig_immediate group doesn't use value 1. Value 3 is instant dig
dig_immediate = {times = {[2] = digtime, [3] = 0}, uses = 0, maxlevel = 256},
}, },
damage_groups = {fleshy = 10}, damage_groups = {fleshy = 10},
} }
}) })
end
if minetest.register_on_mods_loaded then
minetest.register_on_mods_loaded(hand_hack)
else
minetest.after(0.2, hand_hack)
end
end end
-- Unlimited node placement -- Unlimited node placement
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack)
if placer and placer:is_player() then if placer then
return creative.is_enabled_for(placer:get_player_name()) if placer:is_player() then
return creative.is_creative(placer:get_player_name())
end
end end
end) end)
-- Don't pick up if the item is already in the inventory -- Don't pick up if the item is already in the inventory only in hard creative single
local old_handle_node_drops = minetest.handle_node_drops if creative_mode_cache then
function minetest.handle_node_drops(pos, drops, digger) local old_handle_node_drops = minetest.handle_node_drops
if not digger or not digger:is_player() or function minetest.handle_node_drops(pos, drops, digger)
-- not creative.is_enabled_for(digger:get_player_name()) then if not digger then
not creative_mode_cache then if not digger:is_player() then
return old_handle_node_drops(pos, drops, digger) if not creative.is_creative(digger:get_player_name()) then
end return old_handle_node_drops(pos, drops, digger)
local inv = digger:get_inventory() end
if inv then end
for _, item in ipairs(drops) do end
if not inv:contains_item("main", item, true) then local inv = digger:get_inventory()
inv:add_item("main", item) 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
end end
end end
print("[creative] mod loaded")

View File

@ -1,3 +1,3 @@
name = creative name = creative
depends = sfinv depends = sfinv
description = Simplified creative with faster loading description = Simplified creative for more accurate on mobiles or small screens