init.lua 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. local mt, ms = minetest, minetest.settings
  2. local max_distance = tonumber(ms:get "simple_woodcutter.max_distance") or 40
  3. local max_radius = tonumber(ms:get "simple_woodcutter.max_radius") or 1
  4. local delay = tonumber(ms:get "simple_woodcutter.delay") or 0.01
  5. local reverse = ms:get_bool("simple_woodcutter.reverse_modifiers", false)
  6. local only_upward = ms:get_bool("simple_woodcutter.only_upward", true)
  7. local prevent_break = ms:get_bool("simple_woodcutter.prevent_tool_break", true)
  8. local S = mt.get_translator(mt.get_current_modname())
  9. local privilege = { description = S "Player can fell trees quickly." }
  10. ---@param player mt.PlayerObjectRef
  11. ---@return boolean
  12. local function check_modifiers(player)
  13. local control = player:get_player_control() or {}
  14. if reverse then
  15. if not control.aux1 and not control.sneak then return false end
  16. else
  17. if control.aux1 or control.sneak then return false end
  18. end
  19. return true
  20. end
  21. ---@param pos mt.Vector
  22. ---@param oldnode mt.Node
  23. ---@param digger mt.PlayerObjectRef
  24. local function chop_recursive(pos, oldnode, digger)
  25. if not digger or not digger:is_player() then return end
  26. if not check_modifiers(digger) then return end
  27. local node_groups = mt.registered_nodes[oldnode.name].groups
  28. if not node_groups or not node_groups.tree then return end
  29. local tool = digger:get_wielded_item()
  30. if not tool or not tool:get_definition().groups.axe then return end
  31. if prevent_break then
  32. local wear = tool:get_wear()
  33. local tool_capabilities = tool:get_tool_capabilities()
  34. local dig_params = mt.get_dig_params(node_groups, tool_capabilities, wear)
  35. if wear >= 65536 - dig_params.wear * 9 then return end
  36. end
  37. if digger:get_hp() == 0 then return end
  38. local d = delay
  39. if not mt.check_player_privs(digger, "lumberjack") then d = d * 100 end
  40. mt.after(d, function()
  41. local next_pos = mt.find_node_near(pos, max_radius, oldnode.name)
  42. if not next_pos then return end
  43. if only_upward and next_pos.y < pos.y then return end
  44. local digger_pos = digger:get_pos()
  45. if not digger_pos then return end
  46. if pos:distance(digger_pos) > max_distance then return end
  47. mt.node_dig(next_pos, mt.get_node(next_pos), digger)
  48. chop_recursive(pos, oldnode, digger)
  49. end)
  50. end
  51. mt.register_privilege("lumberjack", privilege)
  52. mt.register_on_dignode(chop_recursive)