Slowing creative digging

This commit is contained in:
Johannes Fritz 2023-01-11 12:31:56 -06:00
parent 02ee8b757d
commit a1cc24f8d3
8 changed files with 133 additions and 230 deletions

View file

@ -204,7 +204,7 @@ end
-- Checks if the given node would drop its useful drop if dug by a given tool. -- Checks if the given node would drop its useful drop if dug by a given tool.
-- Returns true if it will yield its useful drop, false otherwise. -- Returns true if it will yield its useful drop, false otherwise.
function mcl_autogroup.can_harvest(nodename, toolname) function mcl_autogroup.can_harvest(nodename, toolname, player)
local ndef = minetest.registered_nodes[nodename] local ndef = minetest.registered_nodes[nodename]
if not ndef then if not ndef then
@ -228,7 +228,9 @@ function mcl_autogroup.can_harvest(nodename, toolname)
end end
-- Check if it can be dug by hand -- Check if it can be dug by hand
local tdef = minetest.registered_tools[""] if not player or not player:is_player() then return false end
local name = player:get_inventory():get_stack("hand", 1):get_name()
local tdef = minetest.registered_items[name]
if tdef then if tdef then
for g, gdef in pairs(tdef._mcl_diggroups) do for g, gdef in pairs(tdef._mcl_diggroups) do
if ndef.groups[g] then if ndef.groups[g] then
@ -260,7 +262,7 @@ local function get_tool_capabilities(tdef)
-- If the damage group and punch interval from hand is not included, -- If the damage group and punch interval from hand is not included,
-- then the user will not be able to attack with the tool. -- then the user will not be able to attack with the tool.
local hand_toolcaps = minetest.registered_tools[""].tool_capabilities local hand_toolcaps = mcl_meshhand.survival_hand_tool_caps
return { return {
full_punch_interval = hand_toolcaps.full_punch_interval, full_punch_interval = hand_toolcaps.full_punch_interval,
damage_groups = hand_toolcaps.damage_groups damage_groups = hand_toolcaps.damage_groups
@ -280,7 +282,7 @@ end
-- would have to add _mcl_autogroup as a dependency which would break the mod -- would have to add _mcl_autogroup as a dependency which would break the mod
-- loading order. -- loading order.
function mcl_autogroup.get_groupcaps(toolname, efficiency) function mcl_autogroup.get_groupcaps(toolname, efficiency)
local tdef = minetest.registered_tools[toolname] local tdef = minetest.registered_items[toolname]
local groupcaps = table.copy(get_tool_capabilities(tdef).groupcaps or {}) local groupcaps = table.copy(get_tool_capabilities(tdef).groupcaps or {})
add_groupcaps(toolname, groupcaps, tdef._mcl_diggroups, efficiency) add_groupcaps(toolname, groupcaps, tdef._mcl_diggroups, efficiency)
return groupcaps return groupcaps
@ -350,7 +352,7 @@ local function overwrite()
end end
end end
for tname, tdef in pairs(minetest.registered_tools) do for tname, tdef in pairs(minetest.registered_items) do
-- Assign groupcaps for digging the registered digging groups -- Assign groupcaps for digging the registered digging groups
-- depending on the _mcl_diggroups in the tool definition -- depending on the _mcl_diggroups in the tool definition
if tdef._mcl_diggroups then if tdef._mcl_diggroups then

View file

@ -1,10 +1,11 @@
# mcl_autogroup # mcl_autogroup
This mod emulate digging times from mc. This mod emulate digging times from mc.
## mcl_autogroup.can_harvest(nodename, toolname) ## mcl_autogroup.can_harvest(nodename, toolname, player)
Return true if <nodename> can be dig with <toolname>. Return true if <nodename> can be dig with <toolname> by <player>.
* nodename: string, valid nodename * nodename: string, valid nodename
* toolname: (optional) string, valid toolname * toolname: (optional) string, valid toolname
* player: (optinal) ObjectRef, valid player
## mcl_autogroup.get_groupcaps(toolname, efficiency) ## mcl_autogroup.get_groupcaps(toolname, efficiency)
This function is used to calculate diggroups for tools. This function is used to calculate diggroups for tools.

View file

@ -252,10 +252,17 @@ function minetest.handle_node_drops(pos, drops, digger)
-- NOTE: This function override allows digger to be nil. -- NOTE: This function override allows digger to be nil.
-- This means there is no digger. This is a special case which allows this function to be called -- This means there is no digger. This is a special case which allows this function to be called
-- by hand. Creative Mode is intentionally ignored in this case. -- by hand. Creative Mode is intentionally ignored in this case.
if digger and digger:is_player() and minetest.is_creative_enabled(digger:get_player_name()) then
if (digger and digger:is_player() and minetest.is_creative_enabled(digger:get_player_name())) or doTileDrops == false then 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
return return
end elseif not doTileDrops then return end
-- Check if node will yield its useful drop by the digger's tool -- Check if node will yield its useful drop by the digger's tool
local dug_node = minetest.get_node(pos) local dug_node = minetest.get_node(pos)
@ -263,9 +270,9 @@ function minetest.handle_node_drops(pos, drops, digger)
local tool local tool
if digger then if digger then
tool = digger:get_wielded_item() tool = digger:get_wielded_item()
tooldef = minetest.registered_tools[tool:get_name()] tooldef = minetest.registered_items[tool:get_name()]
if not mcl_autogroup.can_harvest(dug_node.name, tool:get_name()) then if not mcl_autogroup.can_harvest(dug_node.name, tool:get_name(), digger) then
return return
end end
end end

View file

@ -156,6 +156,7 @@ local function set_inv_page(page, player)
creative_list = inventory_lists[page] creative_list = inventory_lists[page]
end end
inv:set_size("main", #creative_list) inv:set_size("main", #creative_list)
players[playername].inv_size = #creative_list
inv:set_list("main", creative_list) inv:set_list("main", creative_list)
end end
@ -304,37 +305,21 @@ minetest.register_on_joinplayer(function (player)
end end
end) end)
function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size, show, page, filter) function mcl_inventory.set_creative_formspec(player)
--reset_menu_item_bg()
pagenum = math.floor(pagenum) or 1
local playername = player:get_player_name() local playername = player:get_player_name()
if not players[playername] then return end
if not inv_size then local start_i = players[playername].start_i
if page == "nix" then local pagenum = start_i / (9*5) + 1
local inv = minetest.get_inventory({type="detached", name="creative_"..playername}) local name = players[playername].page
inv_size = inv:get_size("main") local inv_size = players[playername].inv_size
elseif page and page ~= "inv" then local filter = players[playername].filter
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 pagemax = math.max(1, math.floor((inv_size-1) / (9*5) + 1))
local name = "nix"
local main_list local main_list
local listrings = "listring[detached:creative_"..playername..";main]".. local listrings = "listring[detached:creative_"..playername..";main]"..
"listring[current_player;main]".. "listring[current_player;main]"..
"listring[detached:trash;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" local inv_bg = "crafting_inventory_creative.png"
if name == "inv" then if name == "inv" then
inv_bg = "crafting_inventory_creative_survival.png" inv_bg = "crafting_inventory_creative_survival.png"
@ -493,9 +478,6 @@ function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size,
listrings listrings
if name == "nix" then 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[5.3,1.34;4,0.75;search;;"..minetest.formspec_escape(filter).."]"
formspec = formspec .. "field_close_on_enter[search;false]" formspec = formspec .. "field_close_on_enter[search;false]"
end end
@ -582,16 +564,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if page then if page then
players[name].page = page players[name].page = page
end else
if players[name].page then
page = players[name].page page = players[name].page
end end
-- Figure out current scroll bar from formspec
--local formspec = player:get_inventory_formspec()
local start_i = players[name].start_i local start_i = players[name].start_i
if fields.creative_prev then if fields.creative_prev then
start_i = start_i - 9*5 start_i = start_i - 9*5
elseif fields.creative_next then elseif fields.creative_next then
@ -613,6 +590,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
else else
inv_size = 0 inv_size = 0
end end
players[name].inv_size = inv_size
if start_i >= inv_size then if start_i >= inv_size then
start_i = start_i - 9*5 start_i = start_i - 9*5
@ -622,72 +600,19 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end end
players[name].start_i = start_i players[name].start_i = start_i
local filter = "" if not fields.nix and fields.search then
if not fields.nix and fields.search and fields.search ~= "" then players[name].filter = fields.search
filter = fields.search else
players[name].filter = filter players[name].filter = ""
end end
mcl_inventory.set_creative_formspec(player, start_i, start_i / (9*5) + 1, inv_size, false, page, filter) mcl_inventory.set_creative_formspec(player)
end) end)
if minetest.is_creative_enabled("") then minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack)
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())
-- Place infinite nodes, except for shulker boxes end)
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) minetest.register_on_joinplayer(function(player)
-- Initialize variables and inventory -- Initialize variables and inventory
@ -700,7 +625,7 @@ minetest.register_on_joinplayer(function(player)
end end
init(player) init(player)
-- Setup initial creative inventory to the "nix" page. -- Setup initial creative inventory to the "nix" page.
mcl_inventory.set_creative_formspec(player, 0, 1, nil, false, "nix", "") mcl_inventory.set_creative_formspec(player)
end) end)
minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info)

View file

@ -46,14 +46,9 @@ function return_fields(player, name)
end end
end end
local function set_inventory(player, armor_change_only) local function set_inventory(player)
if minetest.is_creative_enabled(player:get_player_name()) then if minetest.is_creative_enabled(player:get_player_name()) then
if armor_change_only then mcl_inventory.set_creative_formspec(player)
-- 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 return
end end
local inv = player:get_inventory() local inv = player:get_inventory()
@ -143,11 +138,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end end
end) end)
if not minetest.is_creative_enabled("") then mcl_inventory.update_inventory_formspec = set_inventory
function mcl_inventory.update_inventory_formspec(player)
set_inventory(player)
end
end
-- Drop crafting grid items on leaving -- Drop crafting grid items on leaving
minetest.register_on_leaveplayer(function(player) minetest.register_on_leaveplayer(function(player)
@ -199,24 +190,6 @@ function minetest.is_creative_enabled(name)
return false return false
end end
--Insta "digging" nodes in gamemode-creative
minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing)
if not puncher or not puncher:is_player() then return end
local name = puncher:get_player_name()
if not minetest.is_creative_enabled(name) then return end
if pointed_thing.type ~= "node" then return end
local def = minetest.registered_nodes[node.name]
if def then
minetest.node_dig(pos,node,puncher)
return true
end
end)
--Don't subtract from inv when placing in gamemode-creative
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
if placer and placer:is_player() and minetest.is_creative_enabled(placer:get_player_name()) then return true end
end)
local function in_table(n,h) local function in_table(n,h)
for k,v in pairs(h) do for k,v in pairs(h) do
if v == n then return true end if v == n then return true end
@ -238,6 +211,7 @@ function mcl_inventory.player_set_gamemode(p,g)
elseif g == "creative" then elseif g == "creative" then
mcl_experience.remove_hud(p) mcl_experience.remove_hud(p)
end end
mcl_meshhand.update_player(p)
set_inventory(p) set_inventory(p)
end end

View file

@ -19,50 +19,6 @@ dig_speed_class group:
- 7: Instantaneous - 7: Instantaneous
]] ]]
-- The hand
local groupcaps, hand_range, hand_groups
if minetest.is_creative_enabled("") then
-- Instant breaking in creative mode
groupcaps = { creative_breakable = { times = {0}, uses = 0 } }
hand_range = tonumber(minetest.settings:get("mcl_hand_range_creative")) or 10
hand_groups = { dig_speed_class = 7 }
else
groupcaps = {}
hand_range = tonumber(minetest.settings:get("mcl_hand_range")) or 4.5
hand_groups = { dig_speed_class = 1 }
end
minetest.register_tool(":", {
type = "none",
_doc_items_longdesc = S("You use your bare hand whenever you are not wielding any item. With your hand you can mine most blocks, but this is the slowest method and only the weakest blocks will yield their useful drop. The hand also deals minor damage by punching. Using the hand is often a last resort, as proper mining tools and weapons are much better.").."\n"..
S("When you are wielding an item which is not a mining tool or a weapon, it will behave as if it were the hand when you start mining or punching.").."\n"..
S("In Creative Mode, the hand is able to break all blocks instantly."),
wield_image = "blank.png",
wield_scale = {x=1.0,y=1.0,z=2.0},
-- According to Minecraft Wiki, the exact range is 3.975.
-- Minetest seems to only support whole numbers, so we use 4.
range = hand_range,
tool_capabilities = {
full_punch_interval = 0.25,
max_drop_level = 0,
groupcaps = groupcaps,
damage_groups = {fleshy=1},
},
groups = hand_groups,
_mcl_diggroups = {
handy = { speed = 1, level = 1, uses = 0 },
axey = { speed = 1, level = 1, uses = 0 },
shovely = { speed = 1, level = 1, uses = 0 },
hoey = { speed = 1, level = 1, uses = 0 },
pickaxey = { speed = 1, level = 0, uses = 0 },
swordy = { speed = 1, level = 0, uses = 0 },
swordy_cobweb = { speed = 1, level = 0, uses = 0 },
shearsy = { speed = 1, level = 0, uses = 0 },
shearsy_wool = { speed = 1, level = 0, uses = 0 },
shearsy_cobweb = { speed = 1, level = 0, uses = 0 },
}
})
-- Help texts -- Help texts
local pickaxe_longdesc = S("Pickaxes are mining tools to mine hard blocks, such as stone. A pickaxe can also be used as weapon, but it is rather inefficient.") local pickaxe_longdesc = S("Pickaxes are mining tools to mine hard blocks, such as stone. A pickaxe can also be used as weapon, but it is rather inefficient.")
local axe_longdesc = S("An axe is your tool of choice to cut down trees, wood-based blocks and other blocks. Axes deal a lot of damage as well, but they are rather slow.") local axe_longdesc = S("An axe is your tool of choice to cut down trees, wood-based blocks and other blocks. Axes deal a lot of damage as well, but they are rather slow.")

View file

@ -1,4 +1,5 @@
local mcl_skins_enabled = minetest.global_exists("mcl_skins") local mcl_skins_enabled = minetest.global_exists("mcl_skins")
mcl_meshhand = { }
---This is a fake node that should never be placed in the world ---This is a fake node that should never be placed in the world
---@type node_definition ---@type node_definition
@ -15,43 +16,76 @@ local node_def = {
end, end,
drop = "", drop = "",
on_drop = function(_, _, _) return ItemStack() end, on_drop = function(_, _, _) return ItemStack() end,
groups = { dig_immediate = 3, not_in_creative_inventory = 1 }, groups = {
range = minetest.registered_items[""].range dig_immediate = 3,
not_in_creative_inventory = 1,
dig_speed_class = 1,
},
tool_capabilities = {
full_punch_interval = 0.25,
max_drop_level = 0,
groupcaps = { },
damage_groups = { fleshy = 1 },
},
_mcl_diggroups = {
handy = { speed = 1, level = 1, uses = 0 },
axey = { speed = 1, level = 1, uses = 0 },
shovely = { speed = 1, level = 1, uses = 0 },
hoey = { speed = 1, level = 1, uses = 0 },
pickaxey = { speed = 1, level = 0, uses = 0 },
swordy = { speed = 1, level = 0, uses = 0 },
swordy_cobweb = { speed = 1, level = 0, uses = 0 },
shearsy = { speed = 1, level = 0, uses = 0 },
shearsy_wool = { speed = 1, level = 0, uses = 0 },
shearsy_cobweb = { speed = 1, level = 0, uses = 0 },
},
range = tonumber(minetest.settings:get("mcl_hand_range")) or 4.5
} }
-- This is for _mcl_autogroup to know about the survival hand tool capabilites
mcl_meshhand.survival_hand_tool_caps = node_def.tool_capabilities
local creative_hand_range = tonumber(minetest.settings:get("mcl_hand_range_creative")) or 10
if mcl_skins_enabled then if mcl_skins_enabled then
-- Generate a node for every skin -- Generate a node for every skin
local list = mcl_skins.get_skin_list() local list = mcl_skins.get_skin_list()
for _, skin in pairs(list) do for _, skin in pairs(list) do
if skin.slim_arms then local node_def = table.copy(node_def)
local female = table.copy(node_def) node_def._mcl_hand_id = skin.id
female._mcl_hand_id = skin.id node_def.tiles = { skin.texture }
female.mesh = "mcl_meshhand_female.b3d" node_def.mesh = skin.slim_arms and "mcl_meshhand_female.b3d" or "mcl_meshhand.b3d"
female.tiles = { skin.texture } if skin.creative then
minetest.register_node("mcl_meshhand:" .. skin.id, female) node_def.range = creative_hand_range
else node_def.groups.dig_speed_class = 7
local male = table.copy(node_def) node_def.tool_capabilities.groupcaps.creative_breakable = { times = { 0.1 }, uses = 0 }
male._mcl_hand_id = skin.id
male.mesh = "mcl_meshhand.b3d"
male.tiles = { skin.texture }
minetest.register_node("mcl_meshhand:" .. skin.id, male)
end end
minetest.register_node("mcl_meshhand:" .. skin.id, node_def)
end end
else else
node_def._mcl_hand_id = "hand" node_def._mcl_hand_id = "hand"
node_def.mesh = "mcl_meshhand.b3d" node_def.mesh = "mcl_meshhand.b3d"
node_def.tiles = { "character.png" } node_def.tiles = { "character.png" }
minetest.register_node("mcl_meshhand:hand", node_def) minetest.register_node("mcl_meshhand:hand_surv", node_def)
node_def = table.copy(node_def)
node_def.range = creative_hand_range
node_def.groups.dig_speed_class = 7
node_def.tool_capabilities.groupcaps.creative_breakable = { times = { 0.1 }, uses = 0 }
minetest.register_node("mcl_meshhand:hand_crea", node_def)
end
function mcl_meshhand.update_player(player)
if mcl_skins_enabled then
local node_id = mcl_skins.get_node_id_by_player(player)
player:get_inventory():set_stack("hand", 1, "mcl_meshhand:" .. node_id)
else
local creative = minetest.is_creative_enabled(player:get_player_name())
player:get_inventory():set_stack("hand", 1, "mcl_meshhand:hand" .. (creative and "_crea" or "_surv"))
end
end end
if mcl_skins_enabled then if mcl_skins_enabled then
-- Change the player's hand to their skin mcl_player.register_on_visual_change(mcl_meshhand.update_player)
mcl_player.register_on_visual_change(function(player)
local node_id = mcl_skins.get_node_id_by_player(player)
player:get_inventory():set_stack("hand", 1, "mcl_meshhand:" .. node_id)
end)
else else
minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(mcl_meshhand.update_player)
player:get_inventory():set_stack("hand", 1, ItemStack("mcl_meshhand:hand"))
end)
end end

View file

@ -11,43 +11,47 @@ end
function mcl_skins.get_skin_list() function mcl_skins.get_skin_list()
local list = {} local list = {}
for _, base in pairs(mcl_skins.base) do for _, game_mode in pairs({"_crea", "_surv"}) do
for _, base_color in pairs(mcl_skins.base_color) do for _, base in pairs(mcl_skins.base) do
local id = base:gsub(".png$", "") .. minetest.colorspec_to_colorstring(base_color):gsub("#", "") for _, base_color in pairs(mcl_skins.base_color) do
local female = { local id = base:gsub(".png$", "") .. minetest.colorspec_to_colorstring(base_color):gsub("#", "")
texture = make_texture(base, base_color), local female = {
slim_arms = true, texture = make_texture(base, base_color),
id = id .. "_female" slim_arms = true,
} id = id .. "_female" .. game_mode,
table.insert(list, female) creative = game_mode == "_crea"
}
local male = { table.insert(list, female)
texture = make_texture(base, base_color),
slim_arms = false, local male = {
id = id .. "_male" texture = make_texture(base, base_color),
} slim_arms = false,
table.insert(list, male) id = id .. "_male" .. game_mode,
creative = game_mode == "_crea"
}
table.insert(list, male)
end
end
for _, skin in pairs(mcl_skins.simple_skins) do
table.insert(list, {
texture = skin.texture,
slim_arms = skin.slim_arms,
id = skin.texture:gsub(".png$", "") .. (skin.slim_arms and "_female" or "_male") .. game_mode,
})
end end
end
for _, skin in pairs(mcl_skins.simple_skins) do
table.insert(list, {
texture = skin.texture,
slim_arms = skin.slim_arms,
id = skin.texture:gsub(".png$", "") .. "_" .. (skin.slim_arms and "female" or "male"),
})
end end
return list return list
end end
function mcl_skins.get_node_id_by_player(player) function mcl_skins.get_node_id_by_player(player)
local skin = mcl_skins.players[player] local skin = mcl_skins.players[player]
local creative = minetest.is_creative_enabled(player:get_player_name())
local append = (skin.slim_arms and "_female" or "_male") .. (creative and "_crea" or "_surv")
if skin.simple_skins_id then if skin.simple_skins_id then
local skin = mcl_skins.simple_skins[skin.simple_skins_id] local skin = mcl_skins.simple_skins[skin.simple_skins_id]
return skin.texture:gsub(".png$", "") .. return skin.texture:gsub(".png$", "") .. append
"_" .. (skin.slim_arms and "female" or "male")
else else
return skin.base:gsub(".png$", "") .. return skin.base:gsub(".png$", "") ..
minetest.colorspec_to_colorstring(skin.base_color):gsub("#", "") .. minetest.colorspec_to_colorstring(skin.base_color):gsub("#", "") .. append
"_" .. (skin.slim_arms and "female" or "male")
end end
end end