hoes.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. local S = farming.intllib
  2. local tr = minetest.get_modpath("toolranks")
  3. -- Hoe registration function
  4. farming.register_hoe = function(name, def)
  5. -- Check for : prefix (register new hoes in your mod's namespace)
  6. if name:sub(1,1) ~= ":" then
  7. name = ":" .. name
  8. end
  9. -- Check def table
  10. if def.description == nil then
  11. def.description = S("Hoe")
  12. end
  13. if def.inventory_image == nil then
  14. def.inventory_image = "unknown_item.png"
  15. end
  16. if def.max_uses == nil then
  17. def.max_uses = 30
  18. end
  19. -- Register the tool
  20. minetest.register_tool(name, {
  21. description = def.description,
  22. inventory_image = def.inventory_image,
  23. on_use = function(itemstack, user, pointed_thing)
  24. return farming.hoe_on_use(itemstack, user, pointed_thing, def.max_uses)
  25. end,
  26. groups = def.groups,
  27. sound = {breaks = "default_tool_breaks"},
  28. })
  29. -- Register its recipe
  30. if def.recipe then
  31. minetest.register_craft({
  32. output = name:sub(2),
  33. recipe = def.recipe
  34. })
  35. elseif def.material then
  36. minetest.register_craft({
  37. output = name:sub(2),
  38. recipe = {
  39. {def.material, def.material, ""},
  40. {"", "group:stick", ""},
  41. {"", "group:stick", ""}
  42. }
  43. })
  44. end
  45. end
  46. -- Turns dirt with group soil=1 into soil
  47. function farming.hoe_on_use(itemstack, user, pointed_thing, uses)
  48. local pt = pointed_thing
  49. -- check if pointing at a node
  50. if not pt or pt.type ~= "node" then
  51. return
  52. end
  53. local under = minetest.get_node(pt.under)
  54. local upos = pointed_thing.under
  55. if minetest.is_protected(upos, user:get_player_name()) then
  56. minetest.record_protection_violation(upos, user:get_player_name())
  57. return
  58. end
  59. local p = {x = pt.under.x, y = pt.under.y + 1, z = pt.under.z}
  60. local above = minetest.get_node(p)
  61. -- return if any of the nodes is not registered
  62. if not minetest.registered_nodes[under.name]
  63. or not minetest.registered_nodes[above.name] then
  64. return
  65. end
  66. -- check if the node above the pointed thing is air
  67. if above.name ~= "air" then
  68. return
  69. end
  70. -- check if pointing at dirt
  71. if minetest.get_item_group(under.name, "soil") ~= 1 then
  72. return
  73. end
  74. -- turn the node into soil, wear out item and play sound
  75. minetest.set_node(pt.under, {name = "farming:soil"})
  76. minetest.sound_play("default_dig_crumbly", {pos = pt.under, gain = 0.5})
  77. local wear = 65535 / (uses -1)
  78. if farming.is_creative(user:get_player_name()) then
  79. if tr then
  80. wear = 1
  81. else
  82. wear = 0
  83. end
  84. end
  85. if tr then
  86. itemstack = toolranks.new_afteruse(itemstack, user, under, {wear = wear})
  87. else
  88. itemstack:add_wear(wear)
  89. end
  90. return itemstack
  91. end
  92. -- Define Hoes
  93. farming.register_hoe(":farming:hoe_wood", {
  94. description = S("Wooden Hoe"),
  95. inventory_image = "farming_tool_woodhoe.png",
  96. max_uses = 30,
  97. material = "group:wood"
  98. })
  99. minetest.register_craft({
  100. type = "fuel",
  101. recipe = "farming:hoe_wood",
  102. burntime = 5,
  103. })
  104. farming.register_hoe(":farming:hoe_stone", {
  105. description = S("Stone Hoe"),
  106. inventory_image = "farming_tool_stonehoe.png",
  107. max_uses = 90,
  108. material = "group:stone"
  109. })
  110. farming.register_hoe(":farming:hoe_steel", {
  111. description = S("Steel Hoe"),
  112. inventory_image = "farming_tool_steelhoe.png",
  113. max_uses = 200,
  114. material = "default:steel_ingot"
  115. })
  116. farming.register_hoe(":farming:hoe_bronze", {
  117. description = S("Bronze Hoe"),
  118. inventory_image = "farming_tool_bronzehoe.png",
  119. max_uses = 500,
  120. groups = {not_in_creative_inventory = 1},
  121. })
  122. farming.register_hoe(":farming:hoe_mese", {
  123. description = S("Mese Hoe"),
  124. inventory_image = "farming_tool_mesehoe.png",
  125. max_uses = 350,
  126. groups = {not_in_creative_inventory = 1},
  127. })
  128. farming.register_hoe(":farming:hoe_diamond", {
  129. description = S("Diamond Hoe"),
  130. inventory_image = "farming_tool_diamondhoe.png",
  131. max_uses = 500,
  132. groups = {not_in_creative_inventory = 1},
  133. })
  134. -- Toolranks support
  135. if tr then
  136. minetest.override_item("farming:hoe_wood", {
  137. original_description = "Wood Hoe",
  138. description = toolranks.create_description("Wood Hoe")})
  139. minetest.override_item("farming:hoe_stone", {
  140. original_description = "Stone Hoe",
  141. description = toolranks.create_description("Stone Hoe")})
  142. minetest.override_item("farming:hoe_steel", {
  143. original_description = "Steel Hoe",
  144. description = toolranks.create_description("Steel Hoe")})
  145. minetest.override_item("farming:hoe_bronze", {
  146. original_description = "Bronze Hoe",
  147. description = toolranks.create_description("Bronze Hoe")})
  148. minetest.override_item("farming:hoe_mese", {
  149. original_description = "Mese Hoe",
  150. description = toolranks.create_description("Mese Hoe")})
  151. minetest.override_item("farming:hoe_diamond", {
  152. original_description = "Diamond Hoe",
  153. description = toolranks.create_description("Diamond Hoe")})
  154. end
  155. -- hoe bomb function
  156. local function hoe_area(pos, player)
  157. -- check for protection
  158. if minetest.is_protected(pos, player:get_player_name()) then
  159. minetest.record_protection_violation(pos, player:get_player_name())
  160. return
  161. end
  162. local r = 5 -- radius
  163. -- remove flora (grass, flowers etc.)
  164. local res = minetest.find_nodes_in_area(
  165. {x = pos.x - r, y = pos.y - 1, z = pos.z - r},
  166. {x = pos.x + r, y = pos.y + 2, z = pos.z + r},
  167. {"group:flora"})
  168. for n = 1, #res do
  169. minetest.swap_node(res[n], {name = "air"})
  170. end
  171. -- replace dirt with tilled soil
  172. res = nil
  173. res = minetest.find_nodes_in_area_under_air(
  174. {x = pos.x - r, y = pos.y - 1, z = pos.z - r},
  175. {x = pos.x + r, y = pos.y + 2, z = pos.z + r},
  176. {"group:soil"})
  177. for n = 1, #res do
  178. minetest.swap_node(res[n], {name = "farming:soil"})
  179. end
  180. end
  181. -- throwable hoe bomb
  182. minetest.register_entity("farming:hoebomb_entity", {
  183. physical = true,
  184. visual = "sprite",
  185. visual_size = {x = 1.0, y = 1.0},
  186. textures = {"farming_hoe_bomb.png"},
  187. collisionbox = {0,0,0,0,0,0},
  188. lastpos = {},
  189. player = "",
  190. on_step = function(self, dtime)
  191. if not self.player then
  192. self.object:remove()
  193. return
  194. end
  195. local pos = self.object:get_pos()
  196. if self.lastpos.x ~= nil then
  197. local vel = self.object:getvelocity()
  198. -- only when potion hits something physical
  199. if vel.x == 0
  200. or vel.y == 0
  201. or vel.z == 0 then
  202. if self.player ~= "" then
  203. -- round up coords to fix glitching through doors
  204. self.lastpos = vector.round(self.lastpos)
  205. hoe_area(self.lastpos, self.player)
  206. end
  207. self.object:remove()
  208. return
  209. end
  210. end
  211. self.lastpos = pos
  212. end
  213. })
  214. -- actual throwing function
  215. local function throw_potion(itemstack, player)
  216. local playerpos = player:get_pos()
  217. local obj = minetest.add_entity({
  218. x = playerpos.x,
  219. y = playerpos.y + 1.5,
  220. z = playerpos.z
  221. }, "farming:hoebomb_entity")
  222. local dir = player:get_look_dir()
  223. local velocity = 20
  224. obj:setvelocity({
  225. x = dir.x * velocity,
  226. y = dir.y * velocity,
  227. z = dir.z * velocity
  228. })
  229. obj:setacceleration({
  230. x = dir.x * -3,
  231. y = -9.5,
  232. z = dir.z * -3
  233. })
  234. obj:setyaw(player:get_look_yaw() + math.pi)
  235. obj:get_luaentity().player = player
  236. end
  237. -- hoe bomb item
  238. minetest.register_craftitem("farming:hoe_bomb", {
  239. description = S("Hoe Bomb (use or throw on grassy areas to hoe land"),
  240. inventory_image = "farming_hoe_bomb.png",
  241. groups = {flammable = 2, not_in_creative_inventory = 1},
  242. on_use = function(itemstack, user, pointed_thing)
  243. if pointed_thing.type == "node" then
  244. hoe_area(pointed_thing.above, user)
  245. else
  246. throw_potion(itemstack, user)
  247. if not farming.is_creative(user:get_player_name()) then
  248. itemstack:take_item()
  249. return itemstack
  250. end
  251. end
  252. end,
  253. })
  254. -- Mithril Scythe (special item)
  255. farming.scythe_not_drops = {"farming:trellis", "farming:beanpole"}
  256. farming.add_to_scythe_not_drops = function(item)
  257. table.insert(farming.scythe_not_drops, item)
  258. end
  259. minetest.register_tool("farming:scythe_mithril", {
  260. description = S("Mithril Scythe (Right-click crop to harvest and replant)"),
  261. inventory_image = "farming_scythe_mithril.png",
  262. tool_capabilities = {
  263. full_punch_interval = 0.8,
  264. max_drop_level = 2,
  265. groupcaps = {
  266. fleshy = {times = {[2] = 0.65, [3] = 0.25}, uses = 150, maxlevel = 2},
  267. snappy = {times = {[2] = 0.70, [3] = 0.25}, uses = 150, maxlevel = 2},
  268. },
  269. damage_groups = {fleshy = 8},
  270. },
  271. sound = {breaks = "default_tool_breaks"},
  272. on_place = function(itemstack, placer, pointed_thing)
  273. if pointed_thing.type ~= "node" then
  274. return
  275. end
  276. local pos = pointed_thing.under
  277. local name = placer:get_player_name()
  278. if minetest.is_protected(pos, name) then
  279. return
  280. end
  281. local node = minetest.get_node_or_nil(pos)
  282. if not node then
  283. return
  284. end
  285. local def = minetest.registered_nodes[node.name]
  286. if not def then
  287. return
  288. end
  289. if not def.drop then
  290. return
  291. end
  292. if not def.groups
  293. or not def.groups.plant then
  294. return
  295. end
  296. local drops = minetest.get_node_drops(node.name, "")
  297. if not drops
  298. or #drops == 0
  299. or (#drops == 1 and drops[1] == "") then
  300. return
  301. end
  302. -- get crop name
  303. local mname = node.name:split(":")[1]
  304. local pname = node.name:split(":")[2]
  305. local sname = tonumber(pname:split("_")[2])
  306. pname = pname:split("_")[1]
  307. if not sname then
  308. return
  309. end
  310. -- add dropped items
  311. for _, dropped_item in pairs(drops) do
  312. -- dont drop items on this list
  313. for _, not_item in pairs(farming.scythe_not_drops) do
  314. if dropped_item == not_item then
  315. dropped_item = nil
  316. end
  317. end
  318. if dropped_item then
  319. local obj = minetest.add_item(pos, dropped_item)
  320. if obj then
  321. obj:set_velocity({
  322. x = math.random(-10, 10) / 9,
  323. y = 3,
  324. z = math.random(-10, 10) / 9,
  325. })
  326. end
  327. end
  328. end
  329. -- Run script hook
  330. for _, callback in pairs(core.registered_on_dignodes) do
  331. callback(pos, node)
  332. end
  333. -- play sound
  334. minetest.sound_play("default_grass_footstep", {pos = pos, gain = 1.0})
  335. local replace = mname .. ":" .. pname .. "_1"
  336. if minetest.registered_nodes[replace] then
  337. local p2 = minetest.registered_nodes[replace].place_param2 or 1
  338. minetest.set_node(pos, {name = replace, param2 = p2})
  339. else
  340. minetest.set_node(pos, {name = "air"})
  341. end
  342. if not farming.is_creative(name) then
  343. itemstack:add_wear(65535 / 150) -- 150 uses
  344. return itemstack
  345. end
  346. end,
  347. })
  348. if minetest.get_modpath("moreores") then
  349. minetest.register_craft({
  350. output = "farming:scythe_mithril",
  351. recipe = {
  352. {"", "moreores:mithril_ingot", "moreores:mithril_ingot"},
  353. {"moreores:mithril_ingot", "", "group:stick"},
  354. {"", "", "group:stick"}
  355. }
  356. })
  357. end