api.lua 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. local is_farming_redo = minetest.get_modpath("farming") ~= nil
  2. and farming ~= nil and farming.mod == "redo"
  3. local MAX_ITEM_WEAR = 65535
  4. local DEFAULT_SICKLE_USES = 120
  5. local DEFAULT_SCYTHE_USES = 30
  6. local function is_creative(playername)
  7. return minetest.settings:get_bool("creative_mode")
  8. or minetest.check_player_privs(playername, { creative = true })
  9. end
  10. local function get_wielded_item(player)
  11. if not minetest.is_player(player) then return end
  12. local itemstack = player:get_wielded_item()
  13. if itemstack == nil then return end
  14. return itemstack
  15. end
  16. local function get_item_group(def, group)
  17. if def == nil
  18. or def.groups == nil
  19. or def.groups[group] == nil then
  20. return 0
  21. end
  22. return def.groups[group]
  23. end
  24. function sickles.register_cuttable(nodename, base, item)
  25. local def = minetest.registered_nodes[nodename]
  26. if def == nil then return end
  27. local default_handler = def.on_punch or minetest.node_punch
  28. minetest.override_item(nodename, {
  29. on_punch = function(pos, node, puncher, pointed_thing)
  30. local itemstack = get_wielded_item(puncher)
  31. local itemdef = itemstack:get_definition()
  32. local level = get_item_group(itemdef, "sickle")
  33. if level == 0 then
  34. return default_handler(pos, node, puncher, pointed_thing)
  35. end
  36. local pname = puncher:get_player_name()
  37. if minetest.is_protected(pos, pname) then
  38. minetest.record_protection_violation(pos, pname)
  39. return
  40. end
  41. minetest.handle_node_drops(pos, { item }, puncher)
  42. minetest.after(0, function()
  43. minetest.swap_node(pos, { name = base, param2 = node.param2 })
  44. end)
  45. if not is_creative(pname) then
  46. local max_uses = get_item_group(itemdef, "sickle_uses") or DEFAULT_SICKLE_USES
  47. itemstack:add_wear(math.ceil(MAX_ITEM_WEAR / (max_uses - 1)))
  48. if itemstack:get_count() == 0 and itemdef.sound and itemdef.sound.breaks then
  49. minetest.sound_play(itemdef.sound.breaks, { pos = pos, gain = 0.5 })
  50. end
  51. puncher:set_wielded_item(itemstack)
  52. end
  53. end
  54. })
  55. end
  56. function sickles.register_trimmable(node, base)
  57. local def = minetest.registered_nodes[node]
  58. if def == nil then return end
  59. local handler = def.after_dig_node
  60. minetest.override_item(node, {
  61. after_dig_node = function(pos, oldnode, oldmetadata, digger)
  62. local itemstack = get_wielded_item(digger)
  63. local itemdef = itemstack:get_definition()
  64. local level = get_item_group(itemdef, "sickle")
  65. if level == 0 then
  66. if handler ~= nil then
  67. return handler(pos, oldnode, oldmetadata, digger)
  68. else return end
  69. end
  70. local param2 = minetest.registered_nodes[base].place_param2
  71. minetest.set_node(pos, { name = base, param2 = param2 })
  72. end
  73. })
  74. end
  75. local function get_plant_definition(plant)
  76. if is_farming_redo then
  77. return farming.registered_plants[plant]
  78. else
  79. local mod = plant:split(":")[1] or ""
  80. local name = plant:split(":")[2] or ""
  81. local pname = name:gsub("(.*)_.*$", "%1")
  82. return farming.registered_plants[pname]
  83. end
  84. end
  85. local function get_seed_name(plant)
  86. if is_farming_redo then
  87. return farming.registered_plants[plant].seed
  88. else
  89. local mod = plant:split(":")[1]
  90. local name = plant:split(":")[2]
  91. local pname = name:gsub("(.*)_.*$", "%1")
  92. return mod .. ":seed_" .. pname
  93. end
  94. end
  95. local function harvest_and_replant(pos, player)
  96. local playername = player:get_player_name()
  97. local node = minetest.get_node(pos)
  98. local node_id = node.name:gsub("(.*)_.*$", "%1")
  99. local stage = tonumber(node.name:gsub(".*_(.*)$", "%1") or 0)
  100. local plantdef = get_plant_definition(node_id)
  101. if plantdef == nil or plantdef.steps == nil or stage < plantdef.steps then
  102. return false
  103. end
  104. if minetest.is_protected(pos, playername) then
  105. minetest.record_protection_violation(pos, playername)
  106. return false
  107. end
  108. minetest.node_dig(pos, node, player)
  109. minetest.sound_play("default_dig_snappy", { pos = pos, gain = 0.5, max_hear_distance = 8 }, true)
  110. minetest.after(0, function()
  111. local invref = player:get_inventory()
  112. local seeds = get_seed_name(node_id)
  113. if minetest.get_node(pos).name ~= "air" or
  114. not invref:contains_item("main", seeds) then
  115. return true
  116. end
  117. if not is_creative(playername) then
  118. invref:remove_item("main", seeds)
  119. end
  120. if is_farming_redo then
  121. -- plant first crop for farming redo
  122. local crop_name = node_id .. "_1"
  123. local crop_def = minetest.registered_nodes[crop_name]
  124. if crop_def == nil then return end
  125. minetest.set_node(pos, { name = crop_name, param2 = crop_def.place_param2 })
  126. else
  127. -- plant seeds for MTG farming
  128. minetest.set_node(pos, { name = seeds, param2 = 1 })
  129. -- timer values taken from farming mod (see tick function in api.lua)
  130. minetest.get_node_timer(pos):start(math.random(166, 286))
  131. end
  132. end)
  133. return true
  134. end
  135. function sickles.use_scythe(itemstack, user, pointed_thing)
  136. if pointed_thing == nil then return end
  137. local itemdef = itemstack:get_definition()
  138. if pointed_thing.type == "object" then
  139. local tool_capabilities = itemstack:get_tool_capabilities()
  140. local meta = itemstack:get_meta()
  141. local last_punch = meta:get_float("last_punch") or 0
  142. local now = minetest.get_gametime()
  143. meta:set_float("last_punch", now)
  144. pointed_thing.ref:punch(user, now - last_punch, tool_capabilities)
  145. end
  146. if pointed_thing.type ~= "node" then return end
  147. local max_uses = get_item_group(itemdef, "scythe_uses") or DEFAULT_SCYTHE_USES
  148. local range = (get_item_group(itemdef, "scythe") or 1) - 1
  149. local pos = pointed_thing.under
  150. local harvested = harvest_and_replant(pos, user)
  151. if not harvested then return end
  152. if range > 0 then
  153. local pos1 = vector.add(pos, { x = -range, y = 0, z = -range })
  154. local pos2 = vector.add(pos, { x = range, y = 0, z = range })
  155. local positions = minetest.find_nodes_in_area(pos1, pos2, "group:plant")
  156. for _, check_pos in ipairs(positions) do
  157. if pos ~= check_pos then
  158. harvest_and_replant(check_pos, user)
  159. end
  160. end
  161. end
  162. itemstack:add_wear(math.ceil(MAX_ITEM_WEAR / (max_uses - 1)))
  163. return itemstack
  164. end